Files
2026-03-04 10:03:45 +08:00

88 lines
2.7 KiB
C#

using TriangleNet.Geometry;
using TriangleNet.Tools;
using TriangleNet.Topology.DCEL;
namespace TriangleNet.Voronoi
{
public class BoundedVoronoi : VoronoiBase
{
private int offset;
public BoundedVoronoi(Mesh mesh)
: this(mesh, new DefaultVoronoiFactory(), RobustPredicates.Default)
{
}
public BoundedVoronoi(Mesh mesh, IVoronoiFactory factory, IPredicates predicates)
: base(mesh, factory, predicates, generate: true)
{
offset = vertices.Count;
vertices.Capacity = offset + mesh.hullsize;
PostProcess();
ResolveBoundaryEdges();
}
private void PostProcess()
{
foreach (HalfEdge ray in rays)
{
HalfEdge twin = ray.twin;
TriangleNet.Geometry.Vertex vertex = (TriangleNet.Geometry.Vertex)ray.face.generator;
TriangleNet.Geometry.Vertex vertex2 = (TriangleNet.Geometry.Vertex)twin.face.generator;
if (predicates.CounterClockwise(vertex, vertex2, ray.origin) <= 0.0)
{
HandleCase1(ray, vertex, vertex2);
}
else
{
HandleCase2(ray, vertex, vertex2);
}
}
}
private void HandleCase1(HalfEdge edge, TriangleNet.Geometry.Vertex v1, TriangleNet.Geometry.Vertex v2)
{
TriangleNet.Topology.DCEL.Vertex origin = edge.twin.origin;
origin.x = (v1.x + v2.x) / 2.0;
origin.y = (v1.y + v2.y) / 2.0;
TriangleNet.Topology.DCEL.Vertex vertex = factory.CreateVertex(v1.x, v1.y);
HalfEdge halfEdge = factory.CreateHalfEdge(edge.twin.origin, edge.face);
HalfEdge halfEdge2 = factory.CreateHalfEdge(vertex, edge.face);
edge.next = halfEdge;
halfEdge.next = halfEdge2;
halfEdge2.next = edge.face.edge;
vertex.leaving = halfEdge2;
edge.face.edge = halfEdge2;
edges.Add(halfEdge);
edges.Add(halfEdge2);
halfEdge2.id = (halfEdge.id = edges.Count) + 1;
vertex.id = offset++;
vertices.Add(vertex);
}
private void HandleCase2(HalfEdge edge, TriangleNet.Geometry.Vertex v1, TriangleNet.Geometry.Vertex v2)
{
Point c = edge.origin;
Point c2 = edge.twin.origin;
HalfEdge next = edge.twin.next;
HalfEdge next2 = next.twin.next;
IntersectionHelper.IntersectSegments(v1, v2, next.origin, next.twin.origin, ref c2);
IntersectionHelper.IntersectSegments(v1, v2, next2.origin, next2.twin.origin, ref c);
next.twin.next = edge.twin;
edge.twin.next = next2;
edge.twin.face = next2.face;
next.origin = edge.twin.origin;
edge.twin.twin = null;
edge.twin = null;
TriangleNet.Topology.DCEL.Vertex vertex = factory.CreateVertex(v1.x, v1.y);
HalfEdge halfEdge = (edge.next = factory.CreateHalfEdge(vertex, edge.face));
halfEdge.next = edge.face.edge;
edge.face.edge = halfEdge;
edges.Add(halfEdge);
halfEdge.id = edges.Count;
vertex.id = offset++;
vertices.Add(vertex);
}
}
}