Boprs/Utils.cs

146 lines
4.1 KiB
C#
Raw Normal View History

2024-09-01 13:10:19 +02:00
#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;
2024-09-01 13:10:19 +02:00
/// <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);
}
2024-09-01 13:10:19 +02:00
/// <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);
}
}
}