Compare commits
2 commits
47d3f96b20
...
75d12d6a5a
Author | SHA1 | Date | |
---|---|---|---|
|
75d12d6a5a | ||
|
6744f5e967 |
3 changed files with 32 additions and 37 deletions
|
@ -111,7 +111,12 @@ namespace Boprs
|
||||||
|
|
||||||
BooleanOperation bopr = new BooleanOperation(subject, clip, type);
|
BooleanOperation bopr = new BooleanOperation(subject, clip, type);
|
||||||
|
|
||||||
bopr.Result.Draw();
|
List <Contour> contours = bopr.Result.GetContourCopies();
|
||||||
|
|
||||||
|
foreach (Contour contour in contours)
|
||||||
|
{
|
||||||
|
contour.Draw();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
13
Contour.cs
13
Contour.cs
|
@ -20,17 +20,17 @@ namespace Boprs
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Simple closed polygon.
|
/// Simple closed polygon.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class Contour
|
public class Contour : ICloneable
|
||||||
{
|
{
|
||||||
/// <summary>
|
public object Clone()
|
||||||
/// Depth of the contour within the region.
|
{
|
||||||
/// </summary>
|
return new Contour() { Vertices = new List<Point2d>(Vertices) };
|
||||||
internal int ContourDepth { get; set; }
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Vertices of the contour.
|
/// Vertices of the contour.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public List<Point2d> Vertices { get; }
|
public List<Point2d> Vertices { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Are the vertices of the contour arranged in clockwise manner?
|
/// Are the vertices of the contour arranged in clockwise manner?
|
||||||
|
@ -70,7 +70,6 @@ namespace Boprs
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Contour()
|
public Contour()
|
||||||
{
|
{
|
||||||
ContourDepth = 0;
|
|
||||||
Vertices = new List<Point2d>();
|
Vertices = new List<Point2d>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
49
Region.cs
49
Region.cs
|
@ -151,40 +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,
|
||||||
Point2d target = acVx.Point;
|
// 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;
|
int pos = i;
|
||||||
processed[i] = true;
|
processed[i] = true;
|
||||||
|
Point2d target = acVx.Point;
|
||||||
contour.Vertices.Add(vertices[pos].Point);
|
contour.Vertices.Add(vertices[pos].Point);
|
||||||
acVx.Edge.ParentContour = contour;
|
acVx.Edge.ParentContour = contour;
|
||||||
while (!Utils.DoubleEquals(vertices[pos].OtherVertex().Point.GetDistanceTo(target), 0))
|
while (!Utils.DoubleEquals(vertices[pos].OtherVertex().Point.GetDistanceTo(target), 0))
|
||||||
|
@ -200,6 +193,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();
|
||||||
|
@ -230,7 +224,14 @@ namespace Boprs
|
||||||
/// <returns>List of copies of the regions contours.</returns>
|
/// <returns>List of copies of the regions contours.</returns>
|
||||||
public List<Contour> GetContourCopies()
|
public List<Contour> GetContourCopies()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
List<Contour> copies = new List<Contour>();
|
||||||
|
|
||||||
|
foreach (Contour contour in Contours)
|
||||||
|
{
|
||||||
|
copies.Add((Contour)contour.Clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
return copies;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -257,15 +258,5 @@ namespace Boprs
|
||||||
|
|
||||||
return region;
|
return region;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if DEBUG
|
|
||||||
internal void Draw()
|
|
||||||
{
|
|
||||||
foreach (Contour contour in Contours)
|
|
||||||
{
|
|
||||||
contour.Draw();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue