Files
Dec2017-Script-Dump/Triangle/Tools/Voronoi.cs
T
2026-06-04 11:42:34 +02:00

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;
}
}