Files
HawkeyeVision/Plugins/CandyboxPlugin/Voronoi/Delaunay.cs
2025-09-16 10:42:43 +02:00

79 lines
2.9 KiB
C#

namespace CandyboxPlugin.Voronoi
{
public class DelaunayTriangulator
{
private double MaxX { get; set; }
private double MaxY { get; set; }
private IEnumerable<Triangle> border;
public void GenerateBorder(double maxX, double maxY)
{
MaxX = maxX;
MaxY = maxY;
// TODO make more beautiful
var point0 = new VoronoiPoint(0, 0);
var point1 = new VoronoiPoint(0, MaxY);
var point2 = new VoronoiPoint(MaxX, MaxY);
var point3 = new VoronoiPoint(MaxX, 0);
var points = new List<VoronoiPoint>() { point0, point1, point2, point3 };
var tri1 = new Triangle(point0, point1, point2);
var tri2 = new Triangle(point0, point2, point3);
border = new List<Triangle>() { tri1, tri2 };
}
public IEnumerable<Triangle> BowyerWatson(IEnumerable<VoronoiPoint> points)
{
//var supraTriangle = GenerateSupraTriangle();
var triangulation = new HashSet<Triangle>(border);
foreach (var point in points)
{
var badTriangles = FindBadTriangles(point, triangulation);
var polygon = FindHoleBoundaries(badTriangles);
foreach (var triangle in badTriangles)
{
foreach (var vertex in triangle.Vertices)
{
vertex.AdjacentTriangles.Remove(triangle);
}
}
triangulation.RemoveWhere(o => badTriangles.Contains(o));
foreach (var edge in polygon.Where(possibleEdge => possibleEdge.Point1 != point && possibleEdge.Point2 != point))
{
var triangle = new Triangle(point, edge.Point1, edge.Point2);
triangulation.Add(triangle);
}
}
return triangulation;
}
private List<Edge> FindHoleBoundaries(ISet<Triangle> badTriangles)
{
var edges = new List<Edge>();
foreach (var triangle in badTriangles)
{
edges.Add(new Edge(triangle.Vertices[0], triangle.Vertices[1]));
edges.Add(new Edge(triangle.Vertices[1], triangle.Vertices[2]));
edges.Add(new Edge(triangle.Vertices[2], triangle.Vertices[0]));
}
var grouped = edges.GroupBy(o => o);
var boundaryEdges = edges.GroupBy(o => o).Where(o => o.Count() == 1).Select(o => o.First());
return boundaryEdges.ToList();
}
private ISet<Triangle> FindBadTriangles(VoronoiPoint point, HashSet<Triangle> triangles)
{
var badTriangles = triangles.Where(o => o.IsPointInsideCircumcircle(point));
return new HashSet<Triangle>(badTriangles);
}
}
}