88 lines
2.7 KiB
C#
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);
|
|
}
|
|
}
|
|
}
|