#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 { /// /// End point of an edge used while sweep line is processing a boolean operation. /// internal class SweepVertex : IComparable, ICloneable { /// /// String representation of the vertex. /// public override string ToString() { return ($"({Point.X}, {Point.Y})"); } public object Clone() { return new SweepVertex(Point) { Edge = Edge }; } /// /// Comparison of vertices. /// /// Vertex to compare. /// /// -1 if this is to the left of obj, 1 if this is to the right of obj, 0 if same. /// 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."); } /// /// Position of the vertex, use /// internal Point2d Point { get; } /// /// Edge this vertex belongs to. /// internal SweepEdge Edge { get; set; } /// /// Is this the left vertex of my parent edge? /// /// true if this is the left(or bottom) edge of my parent, false if not. internal bool IsLeft() { return this == Edge.LeftVertex; } /// /// Returns the other vertex associated with my edge. /// /// Other vertex of my edge. internal SweepVertex OtherVertex() { return IsLeft() ? Edge.RightVertex : Edge.LeftVertex; } /// /// Constructor. /// /// Position of the vertex. internal SweepVertex (Point2d point) { Point = point; } } }