using System;
using System.Collections;
using Microsoft.VisualBasic.CompilerServices;

public class DelaunayTriangulation
{
	private class Point
	{
		public double x;

		public double y;

		public double z;

		public Point(double x, double y, double z)
		{
			this.x = x;
			this.y = y;
			this.z = z;
		}

		public static bool operator ==(Point p1, Point p2)
		{
			return (p1.x == p2.x) & (p1.z == p2.z);
		}

		public static bool operator !=(Point p1, Point p2)
		{
			return (p1.x != p2.x) | (p1.z != p2.z);
		}
	}

	private class Line
	{
		public Point p;

		public Point q;

		public Line(Point p1, Point p2)
		{
			p = p1;
			q = p2;
		}

		public static bool operator ==(Line l1, Line l2)
		{
			return ((l1.p == l2.p) & (l1.q == l2.q)) | ((l1.p == l2.q) & (l1.q == l2.p));
		}

		public static bool operator !=(Line l1, Line l2)
		{
			return !(((l1.p == l2.p) & (l1.q == l2.q)) | ((l1.p == l2.q) & (l1.q == l2.p)));
		}
	}

	private class Triangle
	{
		public Point p1;

		public Point p2;

		public Point p3;

		public Line l1;

		public Line l2;

		public Line l3;

		public Circle Circle
		{
			get
			{
				double num = p1.x;
				double z = p1.z;
				double num2 = p2.x;
				double z2 = p2.z;
				double x = p3.x;
				double z3 = p3.z;
				double num3 = z2 - z;
				double num4 = z3 - z2;
				double num5 = 1.1920928955078125E-07;
				bool flag = num4 > 0.0 - num5 && num4 < num5;
				double num6;
				double num7;
				if (num3 > 0.0 - num5 && num3 < num5)
				{
					if (flag)
					{
						if (num2 > num)
						{
							if (x > num2)
							{
								num2 = x;
							}
						}
						else if (x < num)
						{
							num = x;
						}
						num6 = (num + num2) * 0.5;
						num7 = z;
					}
					else
					{
						double num8 = (0.0 - (x - num2)) / num4;
						double num9 = (num2 + x) * 0.5;
						double num10 = (z2 + z3) * 0.5;
						num6 = (num + num2) * 0.5;
						num7 = num8 * (num6 - num9) + num10;
					}
				}
				else if (flag)
				{
					double num11 = (0.0 - (num2 - num)) / num3;
					double num12 = (num + num2) * 0.5;
					double num13 = (z + z2) * 0.5;
					num6 = (num2 + x) * 0.5;
					num7 = num11 * (num6 - num12) + num13;
				}
				else
				{
					double num14 = (0.0 - (num2 - num)) / num3;
					double num15 = (0.0 - (x - num2)) / num4;
					double num16 = (num + num2) * 0.5;
					double num17 = (z + z2) * 0.5;
					double num18 = (num2 + x) * 0.5;
					double num19 = (z2 + z3) * 0.5;
					num6 = (num14 * num16 - num15 * num18 + num19 - num17) / (num14 - num15);
					num7 = num14 * (num6 - num16) + num17;
				}
				double num20 = num - num6;
				double num21 = z - num7;
				double d = num20 * num20 + num21 * num21;
				double num22 = Math.Sqrt(d);
				num22 *= 1.000000000000001;
				return new Circle(num6, num7, num22);
			}
		}

		public Triangle(Point p1, Point p2, Point p3)
		{
			this.p1 = p1;
			this.p2 = p2;
			this.p3 = p3;
			l1 = new Line(p1, p2);
			l2 = new Line(p2, p3);
			l3 = new Line(p3, p1);
		}

		public bool ContainsInCircle(Point p)
		{
			return Circle.get_Contains(p);
		}
	}

	private class Circle
	{
		private double x;

		private double y;

		private double radius;

		public bool Contains
		{
			get
			{
				double num = p.x - x;
				double num2 = p.z - y;
				return Math.Sqrt(num * num + num2 * num2) <= radius;
			}
		}

		public Circle(double x, double y, double radius)
		{
			this.x = x;
			this.y = y;
			this.radius = radius;
		}
	}

	private class SideList
	{
		private class UniqueSide
		{
			public Line side;

			public int count;

			public UniqueSide(Line value)
			{
				side = value;
				count = 1;
			}
		}

		private ArrayList list;

		public ArrayList SideList
		{
			get
			{
				ArrayList arrayList = new ArrayList();
				foreach (UniqueSide item in list)
				{
					if (item.count == 1)
					{
						arrayList.Add(item.side);
					}
				}
				return arrayList;
			}
		}

		public SideList()
		{
			list = new ArrayList();
		}

		public int AddSide(Line value)
		{
			checked
			{
				foreach (UniqueSide item in list)
				{
					if (!(item.side == value))
					{
						continue;
					}
					UniqueSide uniqueSide2 = item;
					uniqueSide2.count++;
					goto IL_006a;
				}
				list.Add(new UniqueSide(value));
				goto IL_006a;
			}
			IL_006a:
			int result = default(int);
			return result;
		}
	}

	private class compareX : IComparer
	{
		public int Compare(object x, object y)
		{
			return Conversions.ToInteger(Operators.CompareObjectLess(NewLateBinding.LateGet(x, null, "x", new object[0], null, null, null), NewLateBinding.LateGet(y, null, "x", new object[0], null, null, null), TextCompare: false));
		}

		int IComparer.Compare(object x, object y)
		{
			//ILSpy generated this explicit interface implementation from .override directive in Compare
			return this.Compare(x, y);
		}
	}

	private ArrayList tris;

	private ArrayList data;

	public ArrayList getPoints
	{
		get
		{
			ArrayList arrayList = new ArrayList();
			foreach (Triangle tri in tris)
			{
				arrayList.Add(new double[3]
				{
					tri.p1.x,
					tri.p1.y,
					tri.p1.z
				});
				arrayList.Add(new double[3]
				{
					tri.p2.x,
					tri.p2.y,
					tri.p2.z
				});
				arrayList.Add(new double[3]
				{
					tri.p3.x,
					tri.p3.y,
					tri.p3.z
				});
			}
			return arrayList;
		}
	}

	public DelaunayTriangulation()
	{
		tris = new ArrayList();
	}

	public void AssignData(ArrayList data)
	{
		this.data = new ArrayList();
		this.data.Clear();
		foreach (float[] datum in data)
		{
			this.data.Add(new Point(datum[0], datum[1], datum[2]));
		}
		object obj = new compareX();
		this.data.Sort((IComparer)obj);
	}

	public void DoTriangulation()
	{
		Point p = new Point(-1000000.0, 0.0, -1000000.0);
		Point p2 = new Point(1000000.0, 0.0, -1000000.0);
		Point p3 = new Point(0.0, 0.0, 1000000.0);
		Triangle triangle = new Triangle(p, p2, p3);
		tris.Clear();
		tris.Add(triangle);
		checked
		{
			int num;
			foreach (Point datum in data)
			{
				num = 0;
				SideList sideList = new SideList();
				while (num < tris.Count)
				{
					Triangle triangle2 = (Triangle)tris[num];
					if (triangle2.ContainsInCircle(datum))
					{
						sideList.AddSide(triangle2.l1);
						sideList.AddSide(triangle2.l2);
						sideList.AddSide(triangle2.l3);
						tris.Remove(triangle2);
					}
					else
					{
						num++;
					}
				}
				foreach (Line side in sideList.SideList)
				{
					tris.Add(new Triangle(side.p, side.q, datum));
				}
			}
			num = 0;
			while (num < tris.Count)
			{
				Triangle triangle2 = (Triangle)tris[num];
				if ((triangle2.p1 == triangle.p1) | (triangle2.p1 == triangle.p2) | (triangle2.p1 == triangle.p3) | (triangle2.p2 == triangle.p1) | (triangle2.p2 == triangle.p2) | (triangle2.p2 == triangle.p3) | (triangle2.p3 == triangle.p1) | (triangle2.p3 == triangle.p2) | (triangle2.p3 == triangle.p3))
				{
					tris.Remove(triangle2);
				}
				else
				{
					num++;
				}
			}
		}
	}
}
