Compare commits
No commits in common. "master" and "1.0.1" have entirely different histories.
9 changed files with 32 additions and 343 deletions
12
Boprs.csproj
12
Boprs.csproj
|
@ -18,7 +18,7 @@
|
||||||
<DebugType>full</DebugType>
|
<DebugType>full</DebugType>
|
||||||
<Optimize>false</Optimize>
|
<Optimize>false</Optimize>
|
||||||
<OutputPath>bin\Debug\</OutputPath>
|
<OutputPath>bin\Debug\</OutputPath>
|
||||||
<DefineConstants>TRACE;DEBUG;BCAD</DefineConstants>
|
<DefineConstants>TRACE;DEBUG;ACAD24</DefineConstants>
|
||||||
<ErrorReport>prompt</ErrorReport>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
@ -41,12 +41,6 @@
|
||||||
<Reference Include="acmgd">
|
<Reference Include="acmgd">
|
||||||
<HintPath>..\..\..\..\..\Program Files\Autodesk\AutoCAD 2024\acmgd.dll</HintPath>
|
<HintPath>..\..\..\..\..\Program Files\Autodesk\AutoCAD 2024\acmgd.dll</HintPath>
|
||||||
</Reference>
|
</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>
|
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
<Reference Include="System.Core" />
|
<Reference Include="System.Core" />
|
||||||
<Reference Include="System.Xml.Linq" />
|
<Reference Include="System.Xml.Linq" />
|
||||||
|
@ -55,14 +49,10 @@
|
||||||
<Reference Include="System.Data" />
|
<Reference Include="System.Data" />
|
||||||
<Reference Include="System.Net.Http" />
|
<Reference Include="System.Net.Http" />
|
||||||
<Reference Include="System.Xml" />
|
<Reference Include="System.Xml" />
|
||||||
<Reference Include="TD_Mgd">
|
|
||||||
<HintPath>..\..\..\..\..\Program Files\Bricsys\BricsCAD V24 en_US\TD_Mgd.dll</HintPath>
|
|
||||||
</Reference>
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="BooleanOperation.cs" />
|
<Compile Include="BooleanOperation.cs" />
|
||||||
<Compile Include="Commands.cs" />
|
<Compile Include="Commands.cs" />
|
||||||
<Compile Include="Contour.cs" />
|
|
||||||
<Compile Include="Region.cs" />
|
<Compile Include="Region.cs" />
|
||||||
<Compile Include="SweepEdge.cs" />
|
<Compile Include="SweepEdge.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
|
11
Commands.cs
11
Commands.cs
|
@ -55,8 +55,6 @@ namespace Boprs
|
||||||
segs.Add(new LineSegment2d(asLine.StartPoint.To2d(), asLine.EndPoint.To2d()));
|
segs.Add(new LineSegment2d(asLine.StartPoint.To2d(), asLine.EndPoint.To2d()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
asPoly.Erase();
|
|
||||||
}
|
}
|
||||||
acTrans.Commit();
|
acTrans.Commit();
|
||||||
}
|
}
|
||||||
|
@ -111,14 +109,7 @@ namespace Boprs
|
||||||
|
|
||||||
BooleanOperation bopr = new BooleanOperation(subject, clip, type);
|
BooleanOperation bopr = new BooleanOperation(subject, clip, type);
|
||||||
|
|
||||||
List <Contour> contours = bopr.Result.GetContourCopies();
|
bopr.Result.Draw();
|
||||||
|
|
||||||
foreach (Contour contour in contours)
|
|
||||||
{
|
|
||||||
contour.Draw();
|
|
||||||
}
|
|
||||||
|
|
||||||
acDoc.Editor.WriteMessage($"\nResult area: {bopr.Result.Area}");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
124
Contour.cs
124
Contour.cs
|
@ -1,124 +0,0 @@
|
||||||
#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;
|
|
||||||
using AcAp = Bricscad.ApplicationServices;
|
|
||||||
#endif
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace Boprs
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Simple closed polygon.
|
|
||||||
/// </summary>
|
|
||||||
public class Contour : ICloneable
|
|
||||||
{
|
|
||||||
public object Clone()
|
|
||||||
{
|
|
||||||
return new Contour(new List<Point2d>(Vertices));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Vertices of the contour.
|
|
||||||
/// </summary>
|
|
||||||
private List<Point2d> Vertices { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Signed area of the contour.
|
|
||||||
/// </summary>
|
|
||||||
public double SignedArea { get; private set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Are the vertices of the contour arranged in clockwise manner?
|
|
||||||
/// </summary>
|
|
||||||
/// <returns><c>true</c> if the contour is clockwise, <c>false</c> if counter-clockwise.</returns>
|
|
||||||
public bool IsClockwise { get => SignedArea < 0; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get a copy of the list of the vertices of this contour.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>List of vertices defining this region.</returns>
|
|
||||||
public List<Point2d> GetVertexCopies()
|
|
||||||
{
|
|
||||||
return new List<Point2d>(Vertices);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Compute the signed area of the contour
|
|
||||||
/// </summary>
|
|
||||||
private void ComputeArea()
|
|
||||||
{
|
|
||||||
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.
|
|
||||||
areaSum += (p1.X - p0.X) * (p1.Y + p0.Y);
|
|
||||||
}
|
|
||||||
|
|
||||||
// The above algorithm deems clockwise area to be positive,
|
|
||||||
// however we consider ccw contours to be positive, so we flip the value.
|
|
||||||
SignedArea = - areaSum / 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Reverse the orientation of the contour.
|
|
||||||
/// </summary>
|
|
||||||
internal void Reverse()
|
|
||||||
{
|
|
||||||
Vertices.Reverse();
|
|
||||||
SignedArea *= -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Constructor.
|
|
||||||
/// </summary>
|
|
||||||
public Contour(List<Point2d> vertices)
|
|
||||||
{
|
|
||||||
Vertices = vertices;
|
|
||||||
ComputeArea();
|
|
||||||
}
|
|
||||||
|
|
||||||
#if DEBUG
|
|
||||||
internal void Draw(Color color = null)
|
|
||||||
{
|
|
||||||
AcAp.Document acDoc = AcAp.Application.DocumentManager.MdiActiveDocument;
|
|
||||||
Database acDb = acDoc.Database;
|
|
||||||
|
|
||||||
using (Transaction acTrans = acDb.TransactionManager.StartTransaction())
|
|
||||||
{
|
|
||||||
// Open the BlockTableRecord
|
|
||||||
BlockTable acBlkTbl = (BlockTable)acTrans.GetObject(acDb.BlockTableId, OpenMode.ForRead);
|
|
||||||
BlockTableRecord acBlkTblRec =
|
|
||||||
(BlockTableRecord)acTrans.GetObject(acBlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite);
|
|
||||||
|
|
||||||
for(int i = 0; i < Vertices.Count; i++)
|
|
||||||
{
|
|
||||||
Line asLine = new Line(Vertices[i].To3d(), Vertices[(i + 1) % Vertices.Count].To3d());
|
|
||||||
asLine.Color = IsClockwise ? Color.FromRgb(255, 32, 32) : Color.FromRgb(32, 255, 32);
|
|
||||||
acBlkTblRec.AppendEntity(asLine);
|
|
||||||
acTrans.AddNewlyCreatedDBObject(asLine, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
acTrans.Commit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
|
||||||
// You can specify all the values or you can default the Build and Revision Numbers
|
// You can specify all the values or you can default the Build and Revision Numbers
|
||||||
// by using the '*' as shown below:
|
// by using the '*' as shown below:
|
||||||
// [assembly: AssemblyVersion("1.0.*")]
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
[assembly: AssemblyVersion("1.1.0.0")]
|
[assembly: AssemblyVersion("1.0.1.0")]
|
||||||
[assembly: AssemblyFileVersion("1.1.0.0")]
|
[assembly: AssemblyFileVersion("1.0.1.0")]
|
||||||
|
|
165
Region.cs
165
Region.cs
|
@ -25,16 +25,6 @@ namespace Boprs
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private List<SweepEdge> Edges { get; set; }
|
private List<SweepEdge> Edges { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Contours making up the region.
|
|
||||||
/// </summary>
|
|
||||||
private List<Contour> Contours { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Area of the positive part of the region (holes subtracted).
|
|
||||||
/// </summary>
|
|
||||||
public double Area { get; private set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Subdivide my edges, set their inOut tags and validate their non-colinearity.
|
/// Subdivide my edges, set their inOut tags and validate their non-colinearity.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -107,124 +97,6 @@ namespace Boprs
|
||||||
Edges = processed;
|
Edges = processed;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Find the index of an un-processed vertex with the same position as the one on specified index.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="pos">Index of the current vertex.</param>
|
|
||||||
/// <param name="vertices">List of vertices.</param>
|
|
||||||
/// <param name="processed">Mask for processed vertices.</param>
|
|
||||||
/// <returns>Index of an unprocessed neighbour with the same position.</returns>
|
|
||||||
private int NextPos(int pos, List<SweepVertex> vertices, bool[] processed)
|
|
||||||
{
|
|
||||||
int newPos = pos + 1;
|
|
||||||
while(newPos < vertices.Count && Utils.PointEquals(vertices[pos].Point, vertices[newPos].Point))
|
|
||||||
{
|
|
||||||
if (!processed[newPos])
|
|
||||||
{
|
|
||||||
return newPos;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
newPos++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
newPos = pos - 1;
|
|
||||||
while (newPos >= 0 && Utils.PointEquals(vertices[pos].Point, vertices[newPos].Point))
|
|
||||||
{
|
|
||||||
if (!processed[newPos])
|
|
||||||
{
|
|
||||||
return newPos;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
newPos--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw new Exception("Hit contour dead end (non-connected edge).");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Compute my closed contours.
|
|
||||||
/// </summary>
|
|
||||||
private void ComputeContours()
|
|
||||||
{
|
|
||||||
// Gather all vertices of the region.
|
|
||||||
List<SweepVertex> vertices = new List<SweepVertex>();
|
|
||||||
foreach (SweepEdge edge in Edges)
|
|
||||||
{
|
|
||||||
vertices.Add(edge.LeftVertex);
|
|
||||||
vertices.Add(edge.RightVertex);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Lexico-graphically sort the vertices.
|
|
||||||
vertices.Sort();
|
|
||||||
|
|
||||||
bool[] processed = new bool[vertices.Count];
|
|
||||||
List<Contour> contours = new List<Contour>();
|
|
||||||
|
|
||||||
for(int i = 0; i < vertices.Count; i++)
|
|
||||||
{
|
|
||||||
// If we already traversed this vertex, skip it.
|
|
||||||
if (processed[i])
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise this is an edge on an indiscovered contour, create it.
|
|
||||||
|
|
||||||
// acVx should be guaranteed to be the lowest and leftest vertex of the new polygon.
|
|
||||||
// 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;
|
|
||||||
|
|
||||||
// Traverse connected edges, and mark taversed vertices as processed,
|
|
||||||
// until we loop back to the first discovered vertex on the contour.
|
|
||||||
int pos = i;
|
|
||||||
processed[i] = true;
|
|
||||||
Point2d target = acVx.Point;
|
|
||||||
List<Point2d> contourVertices = new List<Point2d>() { vertices[pos].Point };
|
|
||||||
while (!Utils.PointEquals(vertices[pos].OtherVertex().Point, target))
|
|
||||||
{
|
|
||||||
int otherPos = vertices.IndexOf(vertices[pos].OtherVertex());
|
|
||||||
pos = NextPos(otherPos, vertices, processed);
|
|
||||||
|
|
||||||
processed[pos] = true;
|
|
||||||
processed[otherPos] = true;
|
|
||||||
|
|
||||||
contourVertices.Add(vertices[pos].Point);
|
|
||||||
}
|
|
||||||
processed[vertices.IndexOf(vertices[pos].OtherVertex())] = true;
|
|
||||||
|
|
||||||
// Instantiate the contour object from the found vertices.
|
|
||||||
Contour contour = new Contour(contourVertices);
|
|
||||||
contours.Add(contour);
|
|
||||||
|
|
||||||
// If the contour is a hole and winds ccw, or positive and winds cw, flip it.
|
|
||||||
if (shouldBeCW != contour.IsClockwise)
|
|
||||||
{
|
|
||||||
contour.Reverse();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Contours = contours;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Compute the area of the region.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// Requires contours to be computed.
|
|
||||||
/// </remarks>
|
|
||||||
private void ComputeArea()
|
|
||||||
{
|
|
||||||
Area = 0;
|
|
||||||
foreach(Contour contour in Contours)
|
|
||||||
{
|
|
||||||
Area += contour.SignedArea;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get a copy of the regions edges list.
|
/// Get a copy of the regions edges list.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -241,22 +113,6 @@ namespace Boprs
|
||||||
return copies;
|
return copies;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get a copy of the contours of the polygon.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>List of copies of the regions contours.</returns>
|
|
||||||
public List<Contour> GetContourCopies()
|
|
||||||
{
|
|
||||||
List<Contour> copies = new List<Contour>();
|
|
||||||
|
|
||||||
foreach (Contour contour in Contours)
|
|
||||||
{
|
|
||||||
copies.Add((Contour)contour.Clone());
|
|
||||||
}
|
|
||||||
|
|
||||||
return copies;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Instantiate a region with edges defined by a list of given line segments.
|
/// Instantiate a region with edges defined by a list of given line segments.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -277,10 +133,27 @@ namespace Boprs
|
||||||
}
|
}
|
||||||
|
|
||||||
region.SetEdges(vertices);
|
region.SetEdges(vertices);
|
||||||
region.ComputeContours();
|
|
||||||
region.ComputeArea();
|
|
||||||
|
|
||||||
return region;
|
return region;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
internal void Draw()
|
||||||
|
{
|
||||||
|
Erase();
|
||||||
|
|
||||||
|
foreach (SweepEdge edge in Edges)
|
||||||
|
{
|
||||||
|
edge.Draw();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
internal void Erase()
|
||||||
|
{
|
||||||
|
foreach (SweepEdge edge in Edges)
|
||||||
|
{
|
||||||
|
edge.Erase();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
14
SweepEdge.cs
14
SweepEdge.cs
|
@ -235,13 +235,13 @@ namespace Boprs
|
||||||
Point2d intPt = intersector.GetIntersectionPoint(0);
|
Point2d intPt = intersector.GetIntersectionPoint(0);
|
||||||
|
|
||||||
// If the point is inside of either edge (not on its end point), subdivide the edge.
|
// If the point is inside of either edge (not on its end point), subdivide the edge.
|
||||||
if (!(Utils.PointEquals(intPt, LeftVertex.Point) ||
|
if (!(Utils.DoubleEquals(intPt.GetDistanceTo(LeftVertex.Point), 0) ||
|
||||||
Utils.PointEquals(intPt, RightVertex.Point)))
|
Utils.DoubleEquals(intPt.GetDistanceTo(RightVertex.Point), 0)))
|
||||||
{
|
{
|
||||||
newVertices.AddRange(SubdivideAt(intPt));
|
newVertices.AddRange(SubdivideAt(intPt));
|
||||||
}
|
}
|
||||||
if (!(Utils.PointEquals(intPt, otherEdge.LeftVertex.Point) ||
|
if (!(Utils.DoubleEquals(intPt.GetDistanceTo(otherEdge.LeftVertex.Point), 0) ||
|
||||||
Utils.PointEquals(intPt, otherEdge.RightVertex.Point)))
|
Utils.DoubleEquals(intPt.GetDistanceTo(otherEdge.RightVertex.Point), 0)))
|
||||||
{
|
{
|
||||||
newVertices.AddRange(otherEdge.SubdivideAt(intPt));
|
newVertices.AddRange(otherEdge.SubdivideAt(intPt));
|
||||||
}
|
}
|
||||||
|
@ -256,14 +256,14 @@ namespace Boprs
|
||||||
List<SweepVertex> newVertices = new List<SweepVertex>();
|
List<SweepVertex> newVertices = new List<SweepVertex>();
|
||||||
|
|
||||||
// The edges share the left vertex
|
// The edges share the left vertex
|
||||||
if (Utils.PointEquals(LeftVertex.Point, otherEdge.LeftVertex.Point))
|
if (Utils.DoubleEquals(LeftVertex.Point.GetDistanceTo(otherEdge.LeftVertex.Point), 0))
|
||||||
{
|
{
|
||||||
EdgeType et = (TransitionInside == otherEdge.TransitionInside) ?
|
EdgeType et = (TransitionInside == otherEdge.TransitionInside) ?
|
||||||
EdgeType.OVERLAP_SAME : EdgeType.OVERLAP_DIFFERENT;
|
EdgeType.OVERLAP_SAME : EdgeType.OVERLAP_DIFFERENT;
|
||||||
|
|
||||||
// The edges share the right vertex as well, set the edge type for both this and the other
|
// The edges share the right vertex as well, set the edge type for both this and the other
|
||||||
// edge and return an empty list.
|
// edge and return an empty list.
|
||||||
if (Utils.PointEquals(RightVertex.Point, otherEdge.RightVertex.Point))
|
if (Utils.DoubleEquals(RightVertex.Point.GetDistanceTo(otherEdge.RightVertex.Point), 0))
|
||||||
{
|
{
|
||||||
Type = et;
|
Type = et;
|
||||||
otherEdge.Type = EdgeType.OVERLAP_SILENT;
|
otherEdge.Type = EdgeType.OVERLAP_SILENT;
|
||||||
|
@ -309,7 +309,7 @@ namespace Boprs
|
||||||
/// <param name="pt2">EndPoint 2.</param>
|
/// <param name="pt2">EndPoint 2.</param>
|
||||||
internal SweepEdge(Point2d pt1, Point2d pt2)
|
internal SweepEdge(Point2d pt1, Point2d pt2)
|
||||||
{
|
{
|
||||||
if (Utils.PointEquals(pt1, pt2))
|
if (Utils.DoubleEquals(pt1.GetDistanceTo(pt2), 0))
|
||||||
{
|
{
|
||||||
throw new ArgumentException("Edge end points cannot be the same.");
|
throw new ArgumentException("Edge end points cannot be the same.");
|
||||||
}
|
}
|
||||||
|
|
21
SweepLine.cs
21
SweepLine.cs
|
@ -77,27 +77,6 @@ namespace Boprs
|
||||||
IntersectingEdges.Remove(edge);
|
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>
|
/// <summary>
|
||||||
/// Returns the edge below curr, or null if curr is the lowest.
|
/// Returns the edge below curr, or null if curr is the lowest.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -119,15 +119,6 @@ namespace Boprs
|
||||||
return this == Edge.LeftVertex;
|
return this == Edge.LeftVertex;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns the other vertex associated with my edge.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>Other vertex of my edge.</returns>
|
|
||||||
internal SweepVertex OtherVertex()
|
|
||||||
{
|
|
||||||
return IsLeft() ? Edge.RightVertex : Edge.LeftVertex;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructor.
|
/// Constructor.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
11
Utils.cs
11
Utils.cs
|
@ -38,17 +38,6 @@ namespace Boprs
|
||||||
return (pt1.X - pt3.X) * (pt2.Y - pt3.Y) - (pt2.X - pt3.X) * (pt1.Y - pt3.Y);
|
return (pt1.X - pt3.X) * (pt2.Y - pt3.Y) - (pt2.X - pt3.X) * (pt1.Y - pt3.Y);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Are the points at roughly the same position?
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="p1">First point to compare.</param>
|
|
||||||
/// <param name="p2">Second point to compare.</param>
|
|
||||||
/// <returns><c>true</c> if the points represent the same position, <c>false</c> if not.</returns>
|
|
||||||
internal static bool PointEquals(Point2d p1, Point2d p2)
|
|
||||||
{
|
|
||||||
return DoubleEquals(p1.X, p2.X) && DoubleEquals(p1.Y, p2.Y);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Are the two doubles close enough to be almost equal?
|
/// Are the two doubles close enough to be almost equal?
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
Loading…
Reference in a new issue