using System; using System.Collections.Generic; using TriangleNet.Data; using TriangleNet.Geometry; namespace TriangleNet.Tools { // Token: 0x02000013 RID: 19 public class BoundedVoronoi : IVoronoi { // Token: 0x060000A3 RID: 163 RVA: 0x00011AFA File Offset: 0x0000FCFA public BoundedVoronoi(Mesh mesh) : this(mesh, true) { } // Token: 0x060000A4 RID: 164 RVA: 0x00011B04 File Offset: 0x0000FD04 public BoundedVoronoi(Mesh mesh, bool includeBoundary) { this.mesh = mesh; this.includeBoundary = includeBoundary; this.Generate(); } // Token: 0x17000020 RID: 32 // (get) Token: 0x060000A5 RID: 165 RVA: 0x00011B27 File Offset: 0x0000FD27 public Point[] Points { get { return this.points; } } // Token: 0x17000021 RID: 33 // (get) Token: 0x060000A6 RID: 166 RVA: 0x00011B2F File Offset: 0x0000FD2F public ICollection Regions { get { return this.regions; } } // Token: 0x060000A7 RID: 167 RVA: 0x00011B38 File Offset: 0x0000FD38 private void Generate() { this.mesh.Renumber(); this.mesh.MakeVertexMap(); this.regions = new List(this.mesh.vertices.Count); this.points = new Point[this.mesh.triangles.Count]; this.segPoints = new List(this.mesh.subsegs.Count * 4); this.ComputeCircumCenters(); this.TagBlindTriangles(); foreach (Vertex vertex in this.mesh.vertices.Values) { if (vertex.type == VertexType.FreeVertex || vertex.Boundary == 0) { this.ConstructCell(vertex); } else if (this.includeBoundary) { this.ConstructBoundaryCell(vertex); } } int num = this.points.Length; Array.Resize(ref this.points, num + this.segPoints.Count); for (int i = 0; i < this.segPoints.Count; i++) { this.points[num + i] = this.segPoints[i]; } this.segPoints.Clear(); this.segPoints = null; } // Token: 0x060000A8 RID: 168 RVA: 0x00011C8C File Offset: 0x0000FE8C 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; } } // Token: 0x060000A9 RID: 169 RVA: 0x00011D44 File Offset: 0x0000FF44 private void TagBlindTriangles() { int num = 0; this.subsegMap = new Dictionary(); Otri otri = default(Otri); Otri otri2 = default(Otri); Osub osub = default(Osub); Osub osub2 = default(Osub); foreach (Triangle triangle in this.mesh.triangles.Values) { triangle.infected = false; } foreach (Segment segment in this.mesh.subsegs.Values) { Stack stack = new Stack(); osub.seg = segment; osub.orient = 0; osub.TriPivot(ref otri); if (otri.triangle != Mesh.dummytri && !otri.triangle.infected) { stack.Push(otri.triangle); } osub.SymSelf(); osub.TriPivot(ref otri); if (otri.triangle != Mesh.dummytri && !otri.triangle.infected) { stack.Push(otri.triangle); } while (stack.Count > 0) { otri.triangle = stack.Pop(); otri.orient = 0; if (this.TriangleIsBlinded(ref otri, ref osub)) { otri.triangle.infected = true; num++; this.subsegMap.Add(otri.triangle.hash, osub.seg); otri.orient = 0; while (otri.orient < 3) { otri.Sym(ref otri2); otri2.SegPivot(ref osub2); if (otri2.triangle != Mesh.dummytri && !otri2.triangle.infected && osub2.seg == Mesh.dummysub) { stack.Push(otri2.triangle); } otri.orient++; } } } } num = 0; } // Token: 0x060000AA RID: 170 RVA: 0x00011F80 File Offset: 0x00010180 private bool TriangleIsBlinded(ref Otri tri, ref Osub seg) { Vertex vertex = tri.Org(); Vertex vertex2 = tri.Dest(); Vertex vertex3 = tri.Apex(); Vertex vertex4 = seg.Org(); Vertex vertex5 = seg.Dest(); Point point = this.points[tri.triangle.id]; Point point2; return this.SegmentsIntersect(vertex4, vertex5, point, vertex, out point2, true) || this.SegmentsIntersect(vertex4, vertex5, point, vertex2, out point2, true) || this.SegmentsIntersect(vertex4, vertex5, point, vertex3, out point2, true); } // Token: 0x060000AB RID: 171 RVA: 0x00012004 File Offset: 0x00010204 private void ConstructCell(Vertex vertex) { VoronoiRegion voronoiRegion = new VoronoiRegion(vertex); this.regions.Add(voronoiRegion); Otri otri = default(Otri); Otri otri2 = default(Otri); Otri otri3 = default(Otri); Osub osub = default(Osub); Osub osub2 = default(Osub); int count = this.mesh.triangles.Count; List list = new List(); vertex.tri.Copy(ref otri2); if (otri2.Org() != vertex) { throw new Exception("ConstructBvdCell: inconsistent topology."); } otri2.Copy(ref otri); otri2.Onext(ref otri3); do { Point point = this.points[otri.triangle.id]; Point point2 = this.points[otri3.triangle.id]; if (!otri.triangle.infected) { list.Add(point); if (otri3.triangle.infected) { osub2.seg = this.subsegMap[otri3.triangle.hash]; Point point3; if (this.SegmentsIntersect(osub2.SegOrg(), osub2.SegDest(), point, point2, out point3, true)) { Point point4 = point3; int num = count; int num2 = this.segIndex; this.segIndex = num2 + 1; point4.id = num + num2; this.segPoints.Add(point3); list.Add(point3); } } } else { osub.seg = this.subsegMap[otri.triangle.hash]; if (!otri3.triangle.infected) { Point point3; if (this.SegmentsIntersect(osub.SegOrg(), osub.SegDest(), point, point2, out point3, true)) { Point point5 = point3; int num3 = count; int num2 = this.segIndex; this.segIndex = num2 + 1; point5.id = num3 + num2; this.segPoints.Add(point3); list.Add(point3); } } else { osub2.seg = this.subsegMap[otri3.triangle.hash]; if (!osub.Equal(osub2)) { Point point3; if (this.SegmentsIntersect(osub.SegOrg(), osub.SegDest(), point, point2, out point3, true)) { Point point6 = point3; int num4 = count; int num2 = this.segIndex; this.segIndex = num2 + 1; point6.id = num4 + num2; this.segPoints.Add(point3); list.Add(point3); } if (this.SegmentsIntersect(osub2.SegOrg(), osub2.SegDest(), point, point2, out point3, true)) { Point point7 = point3; int num5 = count; int num2 = this.segIndex; this.segIndex = num2 + 1; point7.id = num5 + num2; this.segPoints.Add(point3); list.Add(point3); } } } } otri3.Copy(ref otri); otri3.OnextSelf(); } while (!otri.Equal(otri2)); voronoiRegion.Add(list); } // Token: 0x060000AC RID: 172 RVA: 0x000122DC File Offset: 0x000104DC private void ConstructBoundaryCell(Vertex vertex) { VoronoiRegion voronoiRegion = new VoronoiRegion(vertex); this.regions.Add(voronoiRegion); Otri otri = default(Otri); Otri otri2 = default(Otri); Otri otri3 = default(Otri); Otri otri4 = default(Otri); Osub osub = default(Osub); Osub osub2 = default(Osub); int count = this.mesh.triangles.Count; List list = new List(); vertex.tri.Copy(ref otri2); if (otri2.Org() != vertex) { throw new Exception("ConstructBoundaryBvdCell: inconsistent topology."); } otri2.Copy(ref otri); otri2.Onext(ref otri3); otri2.Oprev(ref otri4); if (otri4.triangle != Mesh.dummytri) { while (otri4.triangle != Mesh.dummytri && !otri4.Equal(otri2)) { otri4.Copy(ref otri); otri4.OprevSelf(); } otri.Copy(ref otri2); otri.Onext(ref otri3); } Point point; int num2; if (otri4.triangle == Mesh.dummytri) { point = new Point(vertex.x, vertex.y); Point point2 = point; int num = count; num2 = this.segIndex; this.segIndex = num2 + 1; point2.id = num + num2; this.segPoints.Add(point); list.Add(point); } Vertex vertex2 = otri.Org(); Vertex vertex3 = otri.Dest(); point = new Point((vertex2.X + vertex3.X) / 2.0, (vertex2.Y + vertex3.Y) / 2.0); Point point3 = point; int num3 = count; num2 = this.segIndex; this.segIndex = num2 + 1; point3.id = num3 + num2; this.segPoints.Add(point); list.Add(point); Point point4; Vertex vertex6; for (;;) { point4 = this.points[otri.triangle.id]; if (otri3.triangle == Mesh.dummytri) { break; } Point point5 = this.points[otri3.triangle.id]; if (!otri.triangle.infected) { list.Add(point4); if (otri3.triangle.infected) { osub2.seg = this.subsegMap[otri3.triangle.hash]; if (this.SegmentsIntersect(osub2.SegOrg(), osub2.SegDest(), point4, point5, out point, true)) { Point point6 = point; int num4 = count; num2 = this.segIndex; this.segIndex = num2 + 1; point6.id = num4 + num2; this.segPoints.Add(point); list.Add(point); } } } else { osub.seg = this.subsegMap[otri.triangle.hash]; Vertex vertex4 = osub.SegOrg(); Vertex vertex5 = osub.SegDest(); if (!otri3.triangle.infected) { vertex3 = otri.Dest(); vertex6 = otri.Apex(); Point point7 = new Point((vertex3.X + vertex6.X) / 2.0, (vertex3.Y + vertex6.Y) / 2.0); if (this.SegmentsIntersect(vertex4, vertex5, point7, point4, out point, false)) { Point point8 = point; int num5 = count; num2 = this.segIndex; this.segIndex = num2 + 1; point8.id = num5 + num2; this.segPoints.Add(point); list.Add(point); } if (this.SegmentsIntersect(vertex4, vertex5, point4, point5, out point, true)) { Point point9 = point; int num6 = count; num2 = this.segIndex; this.segIndex = num2 + 1; point9.id = num6 + num2; this.segPoints.Add(point); list.Add(point); } } else { osub2.seg = this.subsegMap[otri3.triangle.hash]; if (!osub.Equal(osub2)) { if (this.SegmentsIntersect(vertex4, vertex5, point4, point5, out point, true)) { Point point10 = point; int num7 = count; num2 = this.segIndex; this.segIndex = num2 + 1; point10.id = num7 + num2; this.segPoints.Add(point); list.Add(point); } if (this.SegmentsIntersect(osub2.SegOrg(), osub2.SegDest(), point4, point5, out point, true)) { Point point11 = point; int num8 = count; num2 = this.segIndex; this.segIndex = num2 + 1; point11.id = num8 + num2; this.segPoints.Add(point); list.Add(point); } } else { Point point12 = new Point((vertex2.X + vertex3.X) / 2.0, (vertex2.Y + vertex3.Y) / 2.0); if (this.SegmentsIntersect(vertex4, vertex5, point12, point5, out point, false)) { Point point13 = point; int num9 = count; num2 = this.segIndex; this.segIndex = num2 + 1; point13.id = num9 + num2; this.segPoints.Add(point); list.Add(point); } } } } otri3.Copy(ref otri); otri3.OnextSelf(); if (otri.Equal(otri2)) { goto IL_5B5; } } if (!otri.triangle.infected) { list.Add(point4); } vertex2 = otri.Org(); vertex6 = otri.Apex(); point = new Point((vertex2.X + vertex6.X) / 2.0, (vertex2.Y + vertex6.Y) / 2.0); Point point14 = point; int num10 = count; num2 = this.segIndex; this.segIndex = num2 + 1; point14.id = num10 + num2; this.segPoints.Add(point); list.Add(point); IL_5B5: voronoiRegion.Add(list); } // Token: 0x060000AD RID: 173 RVA: 0x000128A8 File Offset: 0x00010AA8 private bool SegmentsIntersect(Point p1, Point p2, Point p3, Point p4, out Point p, bool strictIntersect) { p = null; double x = p1.X; double y = p1.Y; double num = p2.X; double num2 = p2.Y; double num3 = p3.X; double num4 = p3.Y; double num5 = p4.X; double num6 = p4.Y; if ((x == num && y == num2) || (num3 == num5 && num4 == num6)) { return false; } if ((x == num3 && y == num4) || (num == num3 && num2 == num4) || (x == num5 && y == num6) || (num == num5 && num2 == num6)) { return false; } num -= x; num2 -= y; num3 -= x; num4 -= y; num5 -= x; num6 -= y; double num7 = Math.Sqrt(num * num + num2 * num2); double num8 = num / num7; double num9 = num2 / num7; double num10 = num3 * num8 + num4 * num9; num4 = num4 * num8 - num3 * num9; num3 = num10; double num11 = num5 * num8 + num6 * num9; num6 = num6 * num8 - num5 * num9; num5 = num11; if ((num4 < 0.0 && num6 < 0.0) || (num4 >= 0.0 && num6 >= 0.0 && strictIntersect)) { return false; } double num12 = num5 + (num3 - num5) * num6 / (num6 - num4); if (num12 < 0.0 || (num12 > num7 && strictIntersect)) { return false; } p = new Point(x + num12 * num8, y + num12 * num9); return true; } // Token: 0x0400008A RID: 138 private Mesh mesh; // Token: 0x0400008B RID: 139 private Point[] points; // Token: 0x0400008C RID: 140 private List regions; // Token: 0x0400008D RID: 141 private List segPoints; // Token: 0x0400008E RID: 142 private int segIndex; // Token: 0x0400008F RID: 143 private Dictionary subsegMap; // Token: 0x04000090 RID: 144 private bool includeBoundary = true; } }