Add Region.Area
This commit is contained in:
parent
dff02947c8
commit
2e57f41125
4 changed files with 60 additions and 24 deletions
|
@ -117,6 +117,8 @@ namespace Boprs
|
|||
{
|
||||
contour.Draw();
|
||||
}
|
||||
|
||||
acDoc.Editor.WriteMessage($"\nResult area: {bopr.Result.Area}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
31
Contour.cs
31
Contour.cs
|
@ -23,19 +23,29 @@ namespace Boprs
|
|||
{
|
||||
public object Clone()
|
||||
{
|
||||
return new Contour() { Vertices = new List<Point2d>(Vertices) };
|
||||
return new Contour(new List<Point2d>(Vertices));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Vertices of the contour.
|
||||
/// </summary>
|
||||
public List<Point2d> Vertices { get; private set; }
|
||||
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()
|
||||
public bool IsClockwise { get => SignedArea < 0; }
|
||||
|
||||
/// <summary>
|
||||
/// Compute the signed area of the contour
|
||||
/// </summary>
|
||||
private void ComputeArea()
|
||||
{
|
||||
double areaSum = 0;
|
||||
|
||||
|
@ -49,27 +59,31 @@ namespace Boprs
|
|||
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.
|
||||
// Note that this is actually double the proper value.
|
||||
areaSum += (p1.X - p0.X) * (p1.Y + p0.Y);
|
||||
}
|
||||
|
||||
return areaSum > 0;
|
||||
// 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>
|
||||
public void Reverse()
|
||||
internal void Reverse()
|
||||
{
|
||||
Vertices.Reverse();
|
||||
SignedArea *= -1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor.
|
||||
/// </summary>
|
||||
public Contour()
|
||||
public Contour(List<Point2d> vertices)
|
||||
{
|
||||
Vertices = new List<Point2d>();
|
||||
Vertices = vertices;
|
||||
ComputeArea();
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
|
@ -88,6 +102,7 @@ namespace Boprs
|
|||
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);
|
||||
}
|
||||
|
|
38
Region.cs
38
Region.cs
|
@ -25,8 +25,16 @@ namespace Boprs
|
|||
/// </summary>
|
||||
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>
|
||||
/// Subdivide my edges, set their inOut tags and validate their non-colinearity.
|
||||
/// </summary>
|
||||
|
@ -163,8 +171,6 @@ namespace Boprs
|
|||
}
|
||||
|
||||
// Otherwise this is an edge on an indiscovered contour, create it.
|
||||
Contour contour = new Contour();
|
||||
contours.Add(contour);
|
||||
|
||||
// acVx should be guaranteed to be the lowest and leftest vertex of the new polygon.
|
||||
// Thus it cannot be vertical.
|
||||
|
@ -178,8 +184,7 @@ namespace Boprs
|
|||
int pos = i;
|
||||
processed[i] = true;
|
||||
Point2d target = acVx.Point;
|
||||
contour.Vertices.Add(vertices[pos].Point);
|
||||
acVx.Edge.ParentContour = contour;
|
||||
List<Point2d> contourVertices = new List<Point2d>() { vertices[pos].Point };
|
||||
while (!Utils.DoubleEquals(vertices[pos].OtherVertex().Point.GetDistanceTo(target), 0))
|
||||
{
|
||||
int otherPos = vertices.IndexOf(vertices[pos].OtherVertex());
|
||||
|
@ -188,13 +193,16 @@ namespace Boprs
|
|||
processed[pos] = true;
|
||||
processed[otherPos] = true;
|
||||
|
||||
vertices[pos].Edge.ParentContour = contour;
|
||||
contour.Vertices.Add(vertices[pos].Point);
|
||||
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())
|
||||
if (shouldBeCW != contour.IsClockwise)
|
||||
{
|
||||
contour.Reverse();
|
||||
}
|
||||
|
@ -202,6 +210,21 @@ namespace Boprs
|
|||
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>
|
||||
/// Get a copy of the regions edges list.
|
||||
/// </summary>
|
||||
|
@ -255,6 +278,7 @@ namespace Boprs
|
|||
|
||||
region.SetEdges(vertices);
|
||||
region.ComputeContours();
|
||||
region.ComputeArea();
|
||||
|
||||
return region;
|
||||
}
|
||||
|
|
|
@ -137,11 +137,6 @@ 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>
|
||||
|
|
Loading…
Reference in a new issue