145 lines
4.1 KiB
C#
145 lines
4.1 KiB
C#
#if ACAD24
|
|
using Autodesk.AutoCAD.EditorInput;
|
|
using Autodesk.AutoCAD.Geometry;
|
|
using Autodesk.AutoCAD.DatabaseServices;
|
|
using Autodesk.AutoCAD.Colors;
|
|
using AcAp = Autodesk.AutoCAD.ApplicationServices;
|
|
#elif BCAD
|
|
using Bricscad.EditorInput;
|
|
using Teigha.Geometry;
|
|
using Teigha.DatabaseServices;
|
|
using Teigha.Colors;
|
|
#endif
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Runtime.CompilerServices;
|
|
|
|
namespace Boprs
|
|
{
|
|
/// <summary>
|
|
/// Non=specific utility functions.
|
|
/// </summary>
|
|
internal static class Utils
|
|
{
|
|
/// <summary>
|
|
/// Largest difference between two doubles before they are considered equal.
|
|
/// </summary>
|
|
internal const double DOUBLEPREC = 1e-8;
|
|
|
|
/// <summary>
|
|
/// Signed area of the triangle (pt1, pt2, pt3).
|
|
/// </summary>
|
|
/// <param name="pt1">Point 1</param>
|
|
/// <param name="pt2">Point 2</param>
|
|
/// <param name="pt3">Point 3</param>
|
|
/// <returns>Signed area of the triangle (pt1, pt2, pt3).</returns>
|
|
internal static double SignedArea(Point2d pt1, Point2d pt2, Point2d pt3)
|
|
{
|
|
return (pt1.X - pt3.X) * (pt2.Y - pt3.Y) - (pt2.X - pt3.X) * (pt1.Y - pt3.Y);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Are the points at roughly the same position?
|
|
/// </summary>
|
|
/// <param name="p1">First point to compare.</param>
|
|
/// <param name="p2">Second point to compare.</param>
|
|
/// <returns><c>true</c> if the points represent the same position, <c>false</c> if not.</returns>
|
|
internal static bool PointEquals(Point2d p1, Point2d p2)
|
|
{
|
|
return DoubleEquals(p1.X, p2.X) && DoubleEquals(p1.Y, p2.Y);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Are the two doubles close enough to be almost equal?
|
|
/// </summary>
|
|
/// <param name="a">First double to compare.</param>
|
|
/// <param name="b">Second double to compare.</param>
|
|
/// <returns><c>true</c> if doubles are almost equal, <c>false</c> if doubles are not equal.</returns>
|
|
internal static bool DoubleEquals(double a, double b)
|
|
{
|
|
return Math.Abs(a - b) < DOUBLEPREC;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get the value Y at a given coordinate X for line going through stPt and endPt.
|
|
/// </summary>
|
|
/// <param name="stPt">Start point of the line.</param>
|
|
/// <param name="endPt">End point of the line.</param>
|
|
/// <param name="x">X param.</param>
|
|
/// <returns>Y value at X param for line going through the 2 points.</returns>
|
|
internal static double YatX(Point2d stPt, Point2d endPt, double x)
|
|
{
|
|
double m = (endPt.Y - stPt.Y) / (endPt.X - stPt.X);
|
|
double b = stPt.Y - (m * stPt.X);
|
|
return m * x + b;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Insert a new vertex inbto a sorted list of vertices such that it remains sorted.
|
|
/// </summary>
|
|
/// <param name="vertices">Sorted list of vertices.</param>
|
|
/// <param name="newElement">Vertex to insert.</param>
|
|
internal static void InsertVertexSorted(List<SweepVertex> vertices, SweepVertex newElement)
|
|
{
|
|
int i = 0;
|
|
|
|
// Go through all the vertices, find my index for insertion.
|
|
for (; i < vertices.Count; i++)
|
|
{
|
|
// If we are left of the current edge, that is the correct index.
|
|
if (newElement.CompareTo(vertices[i]) < 0)
|
|
{
|
|
break;
|
|
}
|
|
// If we are to the right of the last vertex, set inserttion index after it.
|
|
else if (i == vertices.Count - 1)
|
|
{
|
|
i++;
|
|
}
|
|
}
|
|
// Insert the vertex to the correct place.
|
|
vertices.Insert(i, newElement);
|
|
}
|
|
|
|
internal static bool Overlaps(this LineSegment2d me, LineSegment2d other)
|
|
{
|
|
if (!me.IsColinearTo(other))
|
|
{
|
|
return false;
|
|
}
|
|
Line2d commonLine = me.GetLine();
|
|
|
|
double a = commonLine.GetParameterOf(me.StartPoint);
|
|
double b = commonLine.GetParameterOf(me.EndPoint);
|
|
double c = commonLine.GetParameterOf(other.StartPoint);
|
|
double d = commonLine.GetParameterOf(other.EndPoint);
|
|
|
|
if(DoubleEquals(b, c) || DoubleEquals(a, d))
|
|
{
|
|
return false;
|
|
}
|
|
if (b < c || d < a)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Convert a 3d point to 2d.
|
|
/// </summary>
|
|
internal static Point2d To2d(this Point3d pt)
|
|
{
|
|
return new Point2d(pt.X, pt.Y);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Convert a 2d point to 3d.
|
|
/// </summary>
|
|
internal static Point3d To3d(this Point2d pt)
|
|
{
|
|
return new Point3d(pt.X, pt.Y, 0);
|
|
}
|
|
}
|
|
}
|