From 47d3f96b20c963988f56849d6e3e577545a88800 Mon Sep 17 00:00:00 2001 From: borovec zdenek Date: Wed, 4 Sep 2024 13:59:00 +0200 Subject: [PATCH] Contours orientate themselves properly. --- Boprs.csproj | 3 +++ Contour.cs | 26 ++++++++++++++++++++++---- Region.cs | 18 ++++++++++++++---- SweepEdge.cs | 5 +++++ SweepLine.cs | 21 +++++++++++++++++++++ 5 files changed, 65 insertions(+), 8 deletions(-) diff --git a/Boprs.csproj b/Boprs.csproj index 34f83ee..92732e9 100644 --- a/Boprs.csproj +++ b/Boprs.csproj @@ -41,6 +41,9 @@ ..\..\..\..\..\Program Files\Autodesk\AutoCAD 2024\acmgd.dll + + References\BricscadExtensions.dll + ..\..\..\..\..\Program Files\Bricsys\BricsCAD V24 en_US\BrxMgd.dll diff --git a/Contour.cs b/Contour.cs index 50f9432..8d781e4 100644 --- a/Contour.cs +++ b/Contour.cs @@ -13,6 +13,7 @@ using AcAp = Bricscad.ApplicationServices; #endif using System; using System.Collections.Generic; +using BricscadExtensions; namespace Boprs { @@ -22,9 +23,9 @@ namespace Boprs public class Contour { /// - /// Parent of this contour, null if external. + /// Depth of the contour within the region. /// - public Contour Parent { get; internal set; } + internal int ContourDepth { get; set; } /// /// Vertices of the contour. @@ -37,7 +38,23 @@ namespace Boprs /// true if the contour is clockwise, false if counter-clockwise. public bool IsClockwise() { - throw new NotImplementedException(); + double areaSum = 0; + + // Go through all the vertices. + for (int i = 0; i < Vertices.Count; i++) + { + // Get current vertex + Point2d p0 = Vertices[i]; + + // Get the next vertex + Point2d p1 = Vertices[(i + 1) % Vertices.Count]; + + // Compute the area under the trapezoid made by the current segment. + // Note that this is actually double the proper value, but we only care about its relation to 0. + areaSum += (p1.X - p0.X) * (p1.Y + p0.Y); + } + + return areaSum > 0; } /// @@ -45,7 +62,7 @@ namespace Boprs /// public void Reverse() { - throw new NotImplementedException(); + Vertices.Reverse(); } /// @@ -53,6 +70,7 @@ namespace Boprs /// public Contour() { + ContourDepth = 0; Vertices = new List(); } diff --git a/Region.cs b/Region.cs index a4ed208..09b643c 100644 --- a/Region.cs +++ b/Region.cs @@ -174,26 +174,36 @@ namespace Boprs { continue; } - processed[i] = true; - // We should be guaranteed to always hit left endpoint leading us on a counter clockwise path. Contour contour = new Contour(); contours.Add(contour); + SweepEdge prev = sweepLine.PrevEdge(acVx.Edge); + bool shouldBeCW = prev == null ? false : prev.TransitionInside; + Point2d target = acVx.Point; int pos = i; + processed[i] = true; + contour.Vertices.Add(vertices[pos].Point); + acVx.Edge.ParentContour = contour; while (!Utils.DoubleEquals(vertices[pos].OtherVertex().Point.GetDistanceTo(target), 0)) { int otherPos = vertices.IndexOf(vertices[pos].OtherVertex()); pos = NextPos(otherPos, vertices, processed); - contour.Vertices.Add(vertices[pos].Point); processed[pos] = true; - processed[otherPos] = true; + + vertices[pos].Edge.ParentContour = contour; + contour.Vertices.Add(vertices[pos].Point); } processed[vertices.IndexOf(vertices[pos].OtherVertex())] = true; + + if (shouldBeCW != contour.IsClockwise()) + { + contour.Reverse(); + } } Contours = contours; } diff --git a/SweepEdge.cs b/SweepEdge.cs index cbd329d..6334ed8 100644 --- a/SweepEdge.cs +++ b/SweepEdge.cs @@ -137,6 +137,11 @@ namespace Boprs /// internal Region ParentRegion { get; set; } + /// + /// Contour I belong to. + /// + internal Contour ParentContour { get; set; } + /// /// Is this edge vertical? /// diff --git a/SweepLine.cs b/SweepLine.cs index 1435e4c..6d1279b 100644 --- a/SweepLine.cs +++ b/SweepLine.cs @@ -77,6 +77,27 @@ namespace Boprs 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. ///