Contours orientate themselves properly.

This commit is contained in:
borovec zdenek 2024-09-04 13:59:00 +02:00
parent 1a91a64b2d
commit 47d3f96b20
5 changed files with 65 additions and 8 deletions

View file

@ -41,6 +41,9 @@
<Reference Include="acmgd">
<HintPath>..\..\..\..\..\Program Files\Autodesk\AutoCAD 2024\acmgd.dll</HintPath>
</Reference>
<Reference Include="BricscadExtensions">
<HintPath>References\BricscadExtensions.dll</HintPath>
</Reference>
<Reference Include="BrxMgd">
<HintPath>..\..\..\..\..\Program Files\Bricsys\BricsCAD V24 en_US\BrxMgd.dll</HintPath>
</Reference>

View file

@ -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
{
/// <summary>
/// Parent of this contour, null if external.
/// Depth of the contour within the region.
/// </summary>
public Contour Parent { get; internal set; }
internal int ContourDepth { get; set; }
/// <summary>
/// Vertices of the contour.
@ -37,7 +38,23 @@ namespace Boprs
/// <returns><c>true</c> if the contour is clockwise, <c>false</c> if counter-clockwise.</returns>
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;
}
/// <summary>
@ -45,7 +62,7 @@ namespace Boprs
/// </summary>
public void Reverse()
{
throw new NotImplementedException();
Vertices.Reverse();
}
/// <summary>
@ -53,6 +70,7 @@ namespace Boprs
/// </summary>
public Contour()
{
ContourDepth = 0;
Vertices = new List<Point2d>();
}

View file

@ -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;
}

View file

@ -137,6 +137,11 @@ namespace Boprs
/// </summary>
internal Region ParentRegion { get; set; }
/// <summary>
/// Contour I belong to.
/// </summary>
internal Contour ParentContour { get; set; }
/// <summary>
/// Is this edge vertical?
/// </summary>

View file

@ -77,6 +77,27 @@ namespace Boprs
IntersectingEdges.Remove(edge);
}
/// <summary>
/// Get all edges on the sweepline below a given edge.
/// </summary>
/// <param name="curr">Current edge.</param>
/// <returns>From lowest to highest.</returns>
internal List<SweepEdge> AllBefore(SweepEdge curr)
{
List<SweepEdge> foundEdges = new List<SweepEdge>();
// 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;
}
/// <summary>
/// Returns the edge below curr, or null if curr is the lowest.
/// </summary>