Optimize the contour creation.

This commit is contained in:
borovec zdenek 2024-09-04 14:29:30 +02:00
parent 47d3f96b20
commit 6744f5e967

View file

@ -151,38 +151,33 @@ namespace Boprs
// Lexico-graphically sort the vertices. // Lexico-graphically sort the vertices.
vertices.Sort(); vertices.Sort();
// Sweepline to keep track of edges.
SweepLine sweepLine = new SweepLine();
bool[] processed = new bool[vertices.Count]; bool[] processed = new bool[vertices.Count];
List<Contour> contours = new List<Contour>(); List<Contour> contours = new List<Contour>();
for(int i = 0; i < vertices.Count; i++) for(int i = 0; i < vertices.Count; i++)
{ {
SweepVertex acVx = vertices[i]; // If we already traversed this vertex, skip it.
if (acVx.IsLeft())
{
sweepLine.Add(acVx.Edge, false);
}
else
{
sweepLine.Remove(acVx.Edge);
}
if (processed[i]) if (processed[i])
{ {
continue; continue;
} }
// Otherwise this is an edge on an indiscovered contour, create it.
Contour contour = new Contour(); Contour contour = new Contour();
contours.Add(contour); contours.Add(contour);
SweepEdge prev = sweepLine.PrevEdge(acVx.Edge); // acVx should be guaranteed to be the lowest and leftest vertex of the new polygon.
bool shouldBeCW = prev == null ? false : prev.TransitionInside; // Thus it cannot be vertical.
// if it is transition inside, it is a positive contour and should wind counter-clockwise,
// if it is transition outside, it is a negative contour and should wind clockwise.
SweepVertex acVx = vertices[i];
bool shouldBeCW = !acVx.Edge.TransitionInside;
Point2d target = acVx.Point; Point2d target = acVx.Point;
// Traverse connected edges, and mark taversed vertices as processed,
// until we loop back to the first discovered vertex on the contour.
int pos = i; int pos = i;
processed[i] = true; processed[i] = true;
contour.Vertices.Add(vertices[pos].Point); contour.Vertices.Add(vertices[pos].Point);
@ -200,6 +195,7 @@ namespace Boprs
} }
processed[vertices.IndexOf(vertices[pos].OtherVertex())] = true; processed[vertices.IndexOf(vertices[pos].OtherVertex())] = true;
// If the contour is a hole and winds ccw, or positive and winds cw, flip it.
if (shouldBeCW != contour.IsClockwise()) if (shouldBeCW != contour.IsClockwise())
{ {
contour.Reverse(); contour.Reverse();