#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 { /// /// Line to sweep through sorted vertices, keeps track of currently intersecting edges. /// internal class SweepLine { /// /// Edges the line is currently intersecting. /// /// TODO: Change this into a BST when optimizing. private List IntersectingEdges { get; } /// /// Start tracking an edge identified by its left vertex. /// /// Edge to start tracking. /// /// If false and the edge is collinear with one of the edges in the sweep line, /// an exception will get thrown. /// internal void Add(SweepEdge edge, bool allowCollinearity) { int i = 0; if (IntersectingEdges.Contains(edge)) { throw new Exception("inserting contained edge"); } // Go through all the edges, find my index for insertion. for(; i < IntersectingEdges.Count; i++) { int comparison = edge.CompareTo(IntersectingEdges[i], edge.LeftVertex.Point.X); // If we are below the current edge, that is the correct index. if (comparison < 0) { break; } // If edges are collinear and it is not allowed, throw an exception else if(!allowCollinearity && comparison == 0) { throw new Exception($"Collinear edges detected. [{edge} & {IntersectingEdges[i]}]"); } // If we are above the last edge, set inserttion index after it. else if (i == IntersectingEdges.Count) { i++; } } // Insert the edge to the correct place. IntersectingEdges.Insert(i, edge); } /// /// Remove an edge from being tracked by the sweep line. /// /// Edge to remove. internal void Remove(SweepEdge edge) { IntersectingEdges.Remove(edge); } /// /// Get all edges on the sweepline below a given edge. /// /// Current edge. /// From lowest to highest. internal List AllBefore(SweepEdge curr) { List foundEdges = new List(); // Get the index of the current edge int currIdx = IntersectingEdges.IndexOf(curr); // Add all the previous edges to the list for(int i = 0; i < currIdx; i++) { foundEdges.Add(IntersectingEdges[i]); } return foundEdges; } /// /// Returns the edge below curr, or null if curr is the lowest. /// /// Current edge. /// Edge below curr, or null. internal SweepEdge PrevEdge(SweepEdge curr) { // Get the index of the current edge int currIdx = IntersectingEdges.IndexOf(curr); // If the current edge isn't the lowest, return the edge below it. if(currIdx != 0) { return IntersectingEdges[currIdx - 1]; } // Otherwise return null. return null; } /// /// Returns the edge above curr, or null if curr is the highest. /// /// Current edge. /// Edge above curr, or null. internal SweepEdge NextEdge(SweepEdge curr) { // Get the index of the current edge int currIdx = IntersectingEdges.IndexOf(curr); // If the current edge isn't the highest, return the edge above it. if (currIdx != IntersectingEdges.Count - 1) { return IntersectingEdges[currIdx + 1]; } // Otherwise return null. return null; } /// /// Constructor. /// internal SweepLine() { IntersectingEdges = new List(); } } }