243 lines
6.1 KiB
C#
243 lines
6.1 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using TriangleNet.Data;
|
|
using TriangleNet.Geometry;
|
|
|
|
namespace TriangleNet.Tools
|
|
{
|
|
// Token: 0x0200001B RID: 27
|
|
public class Voronoi : IVoronoi
|
|
{
|
|
// Token: 0x060000F6 RID: 246 RVA: 0x00014852 File Offset: 0x00012A52
|
|
public Voronoi(Mesh mesh)
|
|
{
|
|
this.mesh = mesh;
|
|
this.Generate();
|
|
}
|
|
|
|
// Token: 0x17000044 RID: 68
|
|
// (get) Token: 0x060000F7 RID: 247 RVA: 0x00014867 File Offset: 0x00012A67
|
|
public Point[] Points
|
|
{
|
|
get
|
|
{
|
|
return this.points;
|
|
}
|
|
}
|
|
|
|
// Token: 0x17000045 RID: 69
|
|
// (get) Token: 0x060000F8 RID: 248 RVA: 0x0001486F File Offset: 0x00012A6F
|
|
public ICollection<VoronoiRegion> Regions
|
|
{
|
|
get
|
|
{
|
|
return this.regions.Values;
|
|
}
|
|
}
|
|
|
|
// Token: 0x060000F9 RID: 249 RVA: 0x0001487C File Offset: 0x00012A7C
|
|
private void Generate()
|
|
{
|
|
this.mesh.Renumber();
|
|
this.mesh.MakeVertexMap();
|
|
this.points = new Point[this.mesh.triangles.Count + this.mesh.hullsize];
|
|
this.regions = new Dictionary<int, VoronoiRegion>(this.mesh.vertices.Count);
|
|
this.rayPoints = new Dictionary<int, Point>();
|
|
this.rayIndex = 0;
|
|
this.bounds = new BoundingBox();
|
|
this.ComputeCircumCenters();
|
|
foreach (Vertex vertex in this.mesh.vertices.Values)
|
|
{
|
|
this.regions.Add(vertex.id, new VoronoiRegion(vertex));
|
|
}
|
|
foreach (VoronoiRegion voronoiRegion in this.regions.Values)
|
|
{
|
|
this.ConstructVoronoiRegion(voronoiRegion);
|
|
}
|
|
}
|
|
|
|
// Token: 0x060000FA RID: 250 RVA: 0x000149AC File Offset: 0x00012BAC
|
|
private void ComputeCircumCenters()
|
|
{
|
|
Otri otri = default(Otri);
|
|
double num = 0.0;
|
|
double num2 = 0.0;
|
|
foreach (Triangle triangle in this.mesh.triangles.Values)
|
|
{
|
|
otri.triangle = triangle;
|
|
Point point = Primitives.FindCircumcenter(otri.Org(), otri.Dest(), otri.Apex(), ref num, ref num2);
|
|
point.id = triangle.id;
|
|
this.points[triangle.id] = point;
|
|
this.bounds.Expand(point.x, point.y);
|
|
}
|
|
double num3 = Math.Max(this.bounds.Width, this.bounds.Height);
|
|
this.bounds.Resize(num3, num3);
|
|
}
|
|
|
|
// Token: 0x060000FB RID: 251 RVA: 0x00014AA8 File Offset: 0x00012CA8
|
|
private void ConstructVoronoiRegion(VoronoiRegion region)
|
|
{
|
|
Vertex vertex = region.Generator as Vertex;
|
|
List<Point> list = new List<Point>();
|
|
Otri otri = default(Otri);
|
|
Otri otri2 = default(Otri);
|
|
Otri otri3 = default(Otri);
|
|
Otri otri4 = default(Otri);
|
|
Osub osub = default(Osub);
|
|
vertex.tri.Copy(ref otri2);
|
|
otri2.Copy(ref otri);
|
|
otri2.Onext(ref otri3);
|
|
if (otri3.triangle == Mesh.dummytri)
|
|
{
|
|
otri2.Oprev(ref otri4);
|
|
if (otri4.triangle != Mesh.dummytri)
|
|
{
|
|
otri2.Copy(ref otri3);
|
|
otri2.OprevSelf();
|
|
otri2.Copy(ref otri);
|
|
}
|
|
}
|
|
while (otri3.triangle != Mesh.dummytri)
|
|
{
|
|
list.Add(this.points[otri.triangle.id]);
|
|
region.AddNeighbor(otri.triangle.id, this.regions[otri.Apex().id]);
|
|
if (otri3.Equal(otri2))
|
|
{
|
|
region.Add(list);
|
|
return;
|
|
}
|
|
otri3.Copy(ref otri);
|
|
otri3.OnextSelf();
|
|
}
|
|
region.Bounded = false;
|
|
int count = this.mesh.triangles.Count;
|
|
otri.Lprev(ref otri3);
|
|
otri3.SegPivot(ref osub);
|
|
int num = osub.seg.hash;
|
|
list.Add(this.points[otri.triangle.id]);
|
|
region.AddNeighbor(otri.triangle.id, this.regions[otri.Apex().id]);
|
|
Point point;
|
|
if (!this.rayPoints.TryGetValue(num, out point))
|
|
{
|
|
Vertex vertex2 = otri.Org();
|
|
Vertex vertex3 = otri.Apex();
|
|
this.BoxRayIntersection(this.points[otri.triangle.id], vertex2.y - vertex3.y, vertex3.x - vertex2.x, out point);
|
|
point.id = count + this.rayIndex;
|
|
this.points[count + this.rayIndex] = point;
|
|
this.rayIndex++;
|
|
this.rayPoints.Add(num, point);
|
|
}
|
|
list.Add(point);
|
|
list.Reverse();
|
|
otri2.Copy(ref otri);
|
|
otri.Oprev(ref otri4);
|
|
while (otri4.triangle != Mesh.dummytri)
|
|
{
|
|
list.Add(this.points[otri4.triangle.id]);
|
|
region.AddNeighbor(otri4.triangle.id, this.regions[otri4.Apex().id]);
|
|
otri4.Copy(ref otri);
|
|
otri4.OprevSelf();
|
|
}
|
|
otri.SegPivot(ref osub);
|
|
num = osub.seg.hash;
|
|
if (!this.rayPoints.TryGetValue(num, out point))
|
|
{
|
|
Vertex vertex2 = otri.Org();
|
|
Vertex vertex4 = otri.Dest();
|
|
this.BoxRayIntersection(this.points[otri.triangle.id], vertex4.y - vertex2.y, vertex2.x - vertex4.x, out point);
|
|
point.id = count + this.rayIndex;
|
|
this.rayPoints.Add(num, point);
|
|
this.points[count + this.rayIndex] = point;
|
|
this.rayIndex++;
|
|
}
|
|
list.Add(point);
|
|
region.AddNeighbor(point.id, this.regions[otri.Dest().id]);
|
|
list.Reverse();
|
|
region.Add(list);
|
|
}
|
|
|
|
// Token: 0x060000FC RID: 252 RVA: 0x00014E44 File Offset: 0x00013044
|
|
private bool BoxRayIntersection(Point pt, double dx, double dy, out Point intersect)
|
|
{
|
|
double x = pt.X;
|
|
double y = pt.Y;
|
|
double minX = this.bounds.MinX;
|
|
double maxX = this.bounds.MaxX;
|
|
double minY = this.bounds.MinY;
|
|
double maxY = this.bounds.MaxY;
|
|
if (x < minX || x > maxX || y < minY || y > maxY)
|
|
{
|
|
intersect = null;
|
|
return false;
|
|
}
|
|
double num;
|
|
double num2;
|
|
double num3;
|
|
if (dx < 0.0)
|
|
{
|
|
num = (minX - x) / dx;
|
|
num2 = minX;
|
|
num3 = y + num * dy;
|
|
}
|
|
else if (dx > 0.0)
|
|
{
|
|
num = (maxX - x) / dx;
|
|
num2 = maxX;
|
|
num3 = y + num * dy;
|
|
}
|
|
else
|
|
{
|
|
num = double.MaxValue;
|
|
num3 = (num2 = 0.0);
|
|
}
|
|
double num4;
|
|
double num5;
|
|
double num6;
|
|
if (dy < 0.0)
|
|
{
|
|
num4 = (minY - y) / dy;
|
|
num5 = x + num4 * dx;
|
|
num6 = minY;
|
|
}
|
|
else if (dy > 0.0)
|
|
{
|
|
num4 = (maxY - y) / dy;
|
|
num5 = x + num4 * dx;
|
|
num6 = maxY;
|
|
}
|
|
else
|
|
{
|
|
num4 = double.MaxValue;
|
|
num6 = (num5 = 0.0);
|
|
}
|
|
if (num < num4)
|
|
{
|
|
intersect = new Point(num2, num3);
|
|
}
|
|
else
|
|
{
|
|
intersect = new Point(num5, num6);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
// Token: 0x040000C9 RID: 201
|
|
private Mesh mesh;
|
|
|
|
// Token: 0x040000CA RID: 202
|
|
private Point[] points;
|
|
|
|
// Token: 0x040000CB RID: 203
|
|
private Dictionary<int, VoronoiRegion> regions;
|
|
|
|
// Token: 0x040000CC RID: 204
|
|
private Dictionary<int, Point> rayPoints;
|
|
|
|
// Token: 0x040000CD RID: 205
|
|
private int rayIndex;
|
|
|
|
// Token: 0x040000CE RID: 206
|
|
private BoundingBox bounds;
|
|
}
|
|
}
|