Boprs/SweepVertex.cs
2024-09-01 13:10:19 +02:00

126 lines
3.2 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;
namespace Boprs
{
/// <summary>
/// End point of an edge used while sweep line is processing a boolean operation.
/// </summary>
internal class SweepVertex : IComparable
{
/// <summary>
/// String representation of the vertex.
/// </summary>
public override string ToString()
{
return ($"({Point.X}, {Point.Y})");
}
/// <summary>
/// Comparison of vertices.
/// </summary>
/// <param name="obj">Vertex to compare.</param>
/// <returns>
/// <c>-1</c> if this is to the left of obj, <c>1</c> if this is to the right of obj, <c>0</c> if same.
/// </returns>
public int CompareTo(object obj)
{
if (obj is SweepVertex other)
{
// Different x coordinates
if (Point.X > other.Point.X)
{
return 1;
}
// Different x coordinates
if (Point.X < other.Point.X)
{
return -1;
}
// Different points, but same x-coordinate. The event with lower y-coordinate is processed first.
if (Point.Y != other.Point.Y)
{
return Point.Y > other.Point.Y ? 1 : -1;
}
// Same point, but one is a left endpoint and the other a right endpoint.
// The right endpoint is processed first.
if (IsLeft() != other.IsLeft())
{
return IsLeft() ? 1 : -1;
}
// One of our edges is vertical, the non-vertical one gets processed first.
if (Edge.IsVertical() != other.Edge.IsVertical())
{
return Edge.IsVertical() ? 1 : -1;
}
// Left vertex common, the downward leading edge gets processed first.
if (IsLeft())
{
if (Utils.SignedArea(Point, Edge.RightVertex.Point, other.Edge.RightVertex.Point) < 0)
{
return 1;
}
if (Utils.SignedArea(Point, Edge.RightVertex.Point, other.Edge.RightVertex.Point) > 0)
{
return -1;
}
}
// Right vertex is common, the upward leading edge gets processed first.
if (!IsLeft())
{
if (Utils.SignedArea(Point, Edge.RightVertex.Point, other.Edge.RightVertex.Point) < 0)
{
return -1;
}
if (Utils.SignedArea(Point, Edge.RightVertex.Point, other.Edge.RightVertex.Point) > 0)
{
return 1;
}
}
// Colinear edges
return 0;
}
throw new ArgumentException("obj is not SweepEvent.");
}
/// <summary>
/// Position of the vertex, use
/// </summary>
internal Point2d Point { get; }
/// <summary>
/// Edge this vertex belongs to.
/// </summary>
internal SweepEdge Edge { get; set; }
/// <summary>
/// Is this the left vertex of my parent edge?
/// </summary>
/// <returns><c>true</c> if this is the left(or bottom) edge of my parent, <c>false</c> if not.</returns>
internal bool IsLeft()
{
return this == Edge.LeftVertex;
}
/// <summary>
/// Constructor.
/// </summary>
/// <param name="point">Position of the vertex.</param>
internal SweepVertex (Point2d point)
{
Point = point;
}
}
}