Skip to content

Commit 00223ac

Browse files
committed
0.5.5
1 parent c557ad8 commit 00223ac

6 files changed

Lines changed: 56 additions & 117 deletions

File tree

CHANGELOG.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,15 @@
1-
# eppz! <sub>Geometry</sub>
1+
# eppz! `Geometry`
2+
3+
* 0.5.5
4+
5+
+ Only calculated winding direction
6+
+ Removed option to define polygon winding
7+
+ Removed distinct `_signedArea`
8+
+ `area` is always (!) signed
9+
+ Polygon calculations grouped together
10+
+ Renamed to simply `winding`
11+
+ `Geometry`
12+
+ `CentroidOfPolygons` use `area` directly (being always signed)
213

314
* 0.5.1
415

Components/PolygonSource.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ public class PolygonSource : MonoBehaviour
1919

2020

2121
public Transform[] pointTransforms;
22-
public Polygon.WindingDirection windingDirection = Polygon.WindingDirection.Unknown;
2322
[Range (-2,2)] public float offset = 0.0f;
2423
public bool updateModel = false;
2524

@@ -39,7 +38,6 @@ void Update()
3938
{
4039
// Update polygon model with transforms, also update calculations.
4140
polygon.UpdatePointPositionsWithSource(this);
42-
windingDirection = polygon.windingDirection;
4341
if (offset != 0.0f) polygon = polygon.OffsetPolygon(offset);
4442
}
4543
}

Geometry.cs

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -174,28 +174,21 @@ public static bool IsPolygonContainsPoint(Polygon polygon, Vector2 point)
174174
return isOdd;
175175
}
176176

177-
public static Vector2 CentroidOfPolygons(Polygon[] polygons, Polygon.WindingDirection windingDirection = Polygon.WindingDirection.Unknown)
177+
public static Vector2 CentroidOfPolygons(Polygon[] polygons)
178178
{
179-
if (windingDirection == Polygon.WindingDirection.Unknown)
180-
{ windingDirection = polygons[0].windingDirection; }
181-
182179
// From https://en.wikipedia.org/wiki/Centroid#By_geometric_decomposition
183180
float ΣxA = 0.0f;
184181
float ΣyA = 0.0f;
185182
float ΣA = 0.0f;
186183
foreach (Polygon eachPolygon in polygons)
187184
{
188-
// Add or subtract area.
189-
float sign = (eachPolygon.windingDirection == windingDirection) ? 1.0f : -1.0f;
190-
float eachSignedArea = eachPolygon.area * sign;
191-
192185
// Get centroid.
193186
Vector2 eachCentroid = eachPolygon.centroid;
194187

195188
// Sum weighted.
196-
ΣxA += eachCentroid.x * eachSignedArea;
197-
ΣyA += eachCentroid.y * eachSignedArea;
198-
ΣA += eachSignedArea;
189+
ΣxA += eachCentroid.x * eachPolygon.area;
190+
ΣyA += eachCentroid.y * eachPolygon.area;
191+
ΣA += eachPolygon.area;
199192
}
200193

201194
// "Remove" area.

Lines/PolygonLineRenderer.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,12 @@ public class PolygonLineRenderer : GeometryLineRenderer
2424

2525
public Color lineColor;
2626
public Color boundsColor;
27-
public GameObject windingDirectionObject;
27+
public GameObject windingObject;
2828
public TextMesh areaTextMesh;
2929
public bool normals = false;
3030

3131
private float _previousArea;
32-
private Polygon.WindingDirection _previousWindingDirection;
32+
private Polygon.Winding _previousWindingDirection;
3333

3434
public Polygon polygon;
3535

@@ -47,12 +47,12 @@ void Update()
4747
if (polygon == null) return; // Only having polygon
4848

4949
// Layout winding direction object if any.
50-
bool hasWindingDirectionObject = (windingDirectionObject != null);
51-
bool windingChanged = (polygon.windingDirection != _previousWindingDirection);
50+
bool hasWindingDirectionObject = (windingObject != null);
51+
bool windingChanged = (polygon.winding != _previousWindingDirection);
5252
if (hasWindingDirectionObject && windingChanged)
5353
{
54-
windingDirectionObject.transform.localScale = (polygon.isCW) ? Vector3.one : new Vector3 (1.0f, -1.0f, 1.0f);
55-
windingDirectionObject.transform.rotation = (polygon.isCW) ? Quaternion.identity : Quaternion.Euler( new Vector3 (0.0f, 0.0f, 90.0f) );
54+
windingObject.transform.localScale = (polygon.isCW) ? Vector3.one : new Vector3 (1.0f, -1.0f, 1.0f);
55+
windingObject.transform.rotation = (polygon.isCW) ? Quaternion.identity : Quaternion.Euler( new Vector3 (0.0f, 0.0f, 90.0f) );
5656
}
5757

5858
// Layout area text mesh if any.
@@ -64,7 +64,7 @@ void Update()
6464
}
6565

6666
// Track.
67-
_previousWindingDirection = polygon.windingDirection;
67+
_previousWindingDirection = polygon.winding;
6868
_previousArea = polygon.area;
6969
}
7070

Model/Polygon.cs

Lines changed: 32 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
using System;
1010
using System.Collections;
1111
using System.Collections.Generic;
12-
1312
using System.Linq;
1413
using ClipperLib;
1514

@@ -35,12 +34,11 @@ public class Polygon
3534
public string name;
3635

3736
// Windings.
38-
[HideInInspector] public enum WindingDirection { Unknown, CCW, CW };
39-
private WindingDirection _windingDirection = WindingDirection.Unknown;
40-
public WindingDirection windingDirection { get { return _windingDirection; } }
41-
public bool isCW { get { return (_windingDirection == WindingDirection.CW); } }
42-
public bool isCCW { get { return (_windingDirection == WindingDirection.CCW); } }
43-
37+
public bool isCW { get { return (Mathf.Sign(_area) < 0.0f); } }
38+
public bool isCCW { get { return (Mathf.Sign(_area) > 0.0f); } }
39+
public enum Winding { CCW, CW };
40+
public Winding winding { get { return (isCCW) ? Winding.CCW : Winding.CW; } }
41+
4442
/// <remarks>
4543
/// For internal use.
4644
/// Edge, Vertex class can read from this directly
@@ -57,12 +55,9 @@ public class Polygon
5755
private Rect _bounds = new Rect();
5856
public Rect bounds { get { return _bounds; } }
5957

60-
private float _area;
58+
private float _area = 0.0f;
6159
public float area { get { return _area; } }
6260

63-
private float _signedArea;
64-
public float signedArea { get { return _signedArea; } }
65-
6661
// Yet for single polygons only (see centroid of compound polygons).
6762
private Vector2 _centroid;
6863
public Vector2 centroid { get { return _centroid; } }
@@ -75,7 +70,7 @@ public static Polygon PolygonWithPointList(List<Vector2> pointList)
7570

7671
public static Polygon PolygonWithSource(PolygonSource polygonSource)
7772
{
78-
Polygon rootPolygon = Polygon.PolygonWithPointTransforms(polygonSource.pointTransforms, polygonSource.windingDirection);
73+
Polygon rootPolygon = Polygon.PolygonWithPointTransforms(polygonSource.pointTransforms);
7974

8075
// Collect sub-olygons if any.
8176
foreach (Transform eachChildTransform in polygonSource.gameObject.transform)
@@ -112,10 +107,7 @@ public static Polygon PolygonWithPolygon(Polygon polygon)
112107
return rootPolygon;
113108
}
114109

115-
public static Polygon PolygonWithPointTransforms(Transform[] pointTransforms)
116-
{ return PolygonWithPointTransforms(pointTransforms, WindingDirection.Unknown); }
117-
118-
public static Polygon PolygonWithPointTransforms(Transform[] pointTransforms, WindingDirection windingDirection) // Uses Transform.localPosition.xy()
110+
public static Polygon PolygonWithPointTransforms(Transform[] pointTransforms) // Uses Transform.localPosition.xy()
119111
{
120112
// Create points array.
121113
Vector2[] points = new Vector2[pointTransforms.Length];
@@ -125,19 +117,13 @@ public static Polygon PolygonWithPointTransforms(Transform[] pointTransforms, Wi
125117
points[index] = eachPointTransform.localPosition.xy();
126118
}
127119

128-
return Polygon.PolygonWithPoints(points, windingDirection);
120+
return Polygon.PolygonWithPoints(points);
129121
}
130122

131123
public static Polygon PolygonWithPoints(Vector2[] points)
132-
{ return PolygonWithPoints(points, WindingDirection.Unknown); }
133-
134-
public static Polygon PolygonWithPoints(Vector2[] points, WindingDirection windingDirection)
135-
{ return PolygonWithPoints(points, 0.0f, windingDirection); }
124+
{ return PolygonWithPoints(points, 0.0f); }
136125

137126
public static Polygon PolygonWithPoints(Vector2[] points, float angle)
138-
{ return PolygonWithPoints(points, angle, WindingDirection.Unknown); }
139-
140-
public static Polygon PolygonWithPoints(Vector2[] points, float angle, WindingDirection windingDirection)
141127
{
142128
Polygon polygon = new Polygon(points.Length);
143129

@@ -151,10 +137,7 @@ public static Polygon PolygonWithPoints(Vector2[] points, float angle, WindingDi
151137
}
152138

153139
// Polygon calculations.
154-
polygon.CalculateBounds();
155-
polygon.CalculateArea();
156-
polygon.CalculateWindingDirectionIfNeeded();
157-
polygon.CalculateCentroid();
140+
polygon.Calculate();
158141

159142
// Create members.
160143
polygon.CreateVerticesFromPoints();
@@ -189,21 +172,15 @@ public void UpdatePointPositionsWithTransforms(Transform[] pointTransforms) // A
189172
}
190173

191174
// Polygon calculations.
192-
CalculateBounds();
193-
CalculateArea();
194-
CalculateCentroid();
195-
_windingDirection = WindingDirection.Unknown;
196-
CalculateWindingDirectionIfNeeded();
175+
Calculate();
197176
}
198177

199178
public void AddPolygon(Polygon polygon)
200179
{
201180
polygons.Add(polygon);
202181

203182
// Polygon calculations.
204-
CalculateBounds();
205-
CalculateArea();
206-
CalculateCentroid();
183+
Calculate();
207184
}
208185

209186
#endregion
@@ -330,7 +307,14 @@ public void EnumeratePolygons(Action<Polygon> action)
330307

331308
#region Polygon calculations
332309

333-
private void CalculateBounds()
310+
void Calculate()
311+
{
312+
_CalculateBounds();
313+
_CalculateArea();
314+
_CalculateCentroid();
315+
}
316+
317+
void _CalculateBounds()
334318
{
335319
float left = float.MaxValue; // Out in the right
336320
float right = float.MinValue; // Out in the left
@@ -354,27 +338,15 @@ private void CalculateBounds()
354338
_bounds.yMax = top;
355339
}
356340

357-
private void CalculateArea()
341+
private void _CalculateArea()
358342
{
359343

360344
// From https://en.wikipedia.org/wiki/Shoelace_formula
361345
Vector2[] points_ = new Vector2[_points.Length + 1];
362-
363-
// Create point list for calculations.
364-
if (windingDirection == WindingDirection.CW)
365-
{
366-
Vector2[] reversed = new Vector2[_points.Length];
367-
System.Array.Copy(_points, reversed, _points.Length);
368-
System.Array.Copy(reversed, points_, _points.Length);
369-
}
370-
371-
if (windingDirection == WindingDirection.CCW ||
372-
windingDirection == WindingDirection.Unknown)
373-
{ System.Array.Copy(_points, points_, _points.Length); }
374-
346+
System.Array.Copy(_points, points_, _points.Length);
375347
points_[_points.Length] = _points[0];
376348

377-
// Calculations.
349+
// Calculate area.
378350
float firstProducts = 0.0f;
379351
float secondProducts = 0.0f;
380352
for (int index = 0; index < points_.Length - 1; index++)
@@ -385,27 +357,17 @@ private void CalculateArea()
385357
firstProducts += eachPoint.x * eachNextPoint.y;
386358
secondProducts += eachPoint.y * eachNextPoint.x;
387359
}
388-
float area_ = (firstProducts - secondProducts) / 2.0f;
389-
390-
// Set signed area.
391-
_signedArea = area_;
392-
393-
// Set area.
394-
_area = Mathf.Abs(area_);
360+
float _area = (firstProducts - secondProducts) / 2.0f;
395361

396362
// Add / Subtract sub-polygon areas.
397-
float subPolygonAreas = 0.0f;
398363
foreach (Polygon eachPolygon in polygons)
399364
{
400365
// Outer or inner polygon (supposing there is no self-intersection).
401-
float subPolygonArea = eachPolygon.CalculatedArea();
402-
subPolygonAreas += (eachPolygon.windingDirection == windingDirection) ? subPolygonArea : -subPolygonArea;
366+
_area += eachPolygon.area;
403367
}
404-
405-
_area = _area + subPolygonAreas;
406368
}
407369

408-
private void CalculateCentroid()
370+
private void _CalculateCentroid()
409371
{
410372
// Enumerate points.
411373
float Σx = 0.0f;
@@ -423,26 +385,6 @@ private void CalculateCentroid()
423385
// Assign.
424386
_centroid = new Vector2(x, y);
425387
}
426-
427-
private float CalculatedArea()
428-
{
429-
CalculateArea();
430-
return _area;
431-
}
432-
433-
private Vector2 CalculatedCentroid()
434-
{
435-
CalculateCentroid();
436-
return _centroid;
437-
}
438-
439-
private void CalculateWindingDirectionIfNeeded()
440-
{
441-
if (_windingDirection == WindingDirection.Unknown) // Only if unknown
442-
{
443-
_windingDirection = (Mathf.Sign(_signedArea) > 0.0f) ? WindingDirection.CCW : WindingDirection.CW;
444-
}
445-
}
446388

447389
private void CreateVerticesFromPoints()
448390
{
@@ -473,7 +415,7 @@ private void CreateVerticesFromPoints()
473415
firstVertex.SetPreviousVertex(eachVertex);
474416
}
475417

476-
private void CreateEdgesConnectingPoints()
418+
void CreateEdgesConnectingPoints()
477419
{
478420
// Enumerate vertices.
479421
Edge eachEdge = null;
@@ -708,10 +650,9 @@ private Polygon PolygonFromClipperPath(Path path, float scale)
708650

709651
#region Geometry features (Transformations)
710652

711-
public void RecalculateWindindDirection()
653+
public void Reverse()
712654
{
713-
_windingDirection = WindingDirection.Unknown;
714-
CalculateWindingDirectionIfNeeded();
655+
// May be a feature later on (reverse `_points` using `System.Array.Copy()`.
715656
}
716657

717658
public void AlignCentered()
@@ -736,9 +677,7 @@ public void Translate(Vector2 translation)
736677
}
737678

738679
// Polygon calculations.
739-
CalculateBounds();
740-
CalculateArea();
741-
CalculateCentroid();
680+
Calculate();
742681

743682
// Update (bounds).
744683
// _bounds.position += translation;
@@ -762,9 +701,7 @@ public void Scale(Vector2 scale)
762701
}
763702

764703
// Polygon calculations.
765-
CalculateBounds();
766-
CalculateArea();
767-
CalculateCentroid();
704+
Calculate();
768705
}
769706

770707
#endregion

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
44
**📐 2D geometry for Unity.**
55

6-
Polygon triangulation, Voronoi diagram, polygon offset, polygon outline, union of polygons, substraction of polygons. polygon clipping, polygon winding direction, polygon area, polygon centroid, centroid of multiple polygons, line intersection, point-line distance, segment intersection, polygon-point containment, and more.
6+
Polygon clipping, polygon winding direction, polygon area, polygon centroid, centroid of multiple polygons, line intersection, point-line distance, segment intersection, polygon-point containment, polygon triangulation, polygon Voronoi diagram, polygon offset, polygon outline, polygon buffer, polygon union, polygon substraction, polygon boolean operations, and more. It is a polygon fest.
77

88
The library is **being used in production**. However, it comes with the disclaimed liability and warranty of [MIT License](https://en.wikipedia.org/wiki/MIT_License).
99

0 commit comments

Comments
 (0)