Add polygon shape
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace StructureHelperCommon.Models.Shapes
|
||||
{
|
||||
public static class PolygonGeometryUtils
|
||||
{
|
||||
public static bool DoPolygonsEdgesIntersect(IPolygonShape polygon)
|
||||
{
|
||||
var vertices = polygon.Vertices;
|
||||
int n = vertices.Count;
|
||||
|
||||
if (n < 4)
|
||||
return false; // Triangles cannot self-intersect
|
||||
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
var a1 = vertices[i].Point;
|
||||
var a2 = vertices[(i + 1) % n].Point;
|
||||
|
||||
for (int j = i + 1; j < n; j++)
|
||||
{
|
||||
var b1 = vertices[j].Point;
|
||||
var b2 = vertices[(j + 1) % n].Point;
|
||||
|
||||
// Skip adjacent edges (they share a vertex)
|
||||
if (AreAdjacent(i, j, n, polygon.IsClosed))
|
||||
continue;
|
||||
|
||||
if (SegmentsIntersect(a1, a2, b1, b2))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool AreAdjacent(int i, int j, int n, bool isClosed)
|
||||
{
|
||||
// Edges (i,i+1) and (j,j+1) are adjacent if:
|
||||
if (j == i) return true;
|
||||
if (j == i + 1) return true;
|
||||
if (i == j + 1) return true;
|
||||
|
||||
// Special case: first and last edges in closed polygon
|
||||
if (isClosed &&
|
||||
((i == 0 && j == n - 1) || (j == 0 && i == n - 1)))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool SegmentsIntersect(IPoint2D p1, IPoint2D p2, IPoint2D q1, IPoint2D q2)
|
||||
{
|
||||
return (Orientation(p1, p2, q1) * Orientation(p1, p2, q2) < 0) &&
|
||||
(Orientation(q1, q2, p1) * Orientation(q1, q2, p2) < 0);
|
||||
}
|
||||
|
||||
private static int Orientation(IPoint2D a, IPoint2D b, IPoint2D c)
|
||||
{
|
||||
double val = (b.Y - a.Y) * (c.X - b.X) -
|
||||
(b.X - a.X) * (c.Y - b.Y);
|
||||
|
||||
if (Math.Abs(val) < 1e-12) return 0; // Collinear
|
||||
return (val > 0) ? 1 : -1; // Clockwise / Counter-clockwise
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user