/// <summary> /// Delta distance squared between this and other vertex t /// </summary> /// <param name="t"></param> /// <returns></returns> public float DeltaSquared(Vertex t) { float dx = (X - t.X); float dy = (Y - t.Y); float dz = (Z - t.Z); return (dx * dx) + (dy * dy) + (dz * dz); }
/// <summary> /// Insert. /// </summary> /// <param name="v"></param> /// <param name="old"></param> protected void Insert(Vertex v, Triangle old) { // Avoid duplicates, if this facet contains v as a vertex, // just return. if ((old.A.X == v.X) && (old.A.Y == v.Y)) return; if ((old.B.X == v.X) && (old.B.Y == v.Y)) return; if ((old.C.X == v.X) && (old.C.Y == v.Y)) return; m_points.Add(v); // Split old into 3 triangles, // Because old is counter clockwise, when duplicated, // ab, bc, ca is counter clockwise. // By changing one point and keeping to the commutation, // they remain counter clockwise. Triangle ab = new Triangle(old); // contains old ab, v is new C. Triangle bc = new Triangle(old); // contains old bc, v is new A. Triangle ca = new Triangle(old); // contains old ca, v is new B. ab.C = v; bc.A = v; ca.B = v; // This also makes assigning the sides easy. ab.BC = bc; ab.CA = ca; bc.AB = ab; bc.CA = ca; ca.AB = ab; ca.BC = bc; // The existing trianges that share an edge with old, // now share an edge with one of the three new triangles. // Repair the existing. // One way of looking at it: // for (int j = 0; j < 3; j++) // { // if ((ab.AB != null) && (ab.AB.Edge(j) == old)) ab.AB.SetEdge(j, ab); // if ((bc.BC != null) && (bc.BC.Edge(j) == old)) bc.BC.SetEdge(j, bc); // if ((ca.CA != null) && (ca.CA.Edge(j) == old)) ca.CA.SetEdge(j, ca); // } // This is faster, null check is once per edge, and default logic // reduces the compares by one. Instead of 3*3*2 comparisons = 18, // Worst case is 3*3 = 9, Average is 2+3+3=8. Triangle[] ta = { ab.AB, bc.BC, ca.CA }; Triangle[] tb = { ab, bc, ca }; for (int j = 0; j < 3; j++) { if (ta[j] == null) continue; if (ta[j].Edge(0) == old) { ta[j].SetEdge(0, tb[j]); continue; } if (ta[j].Edge(1) == old) { ta[j].SetEdge(1, tb[j]); continue; } ta[j].SetEdge(2, tb[j]); } // Add the new, remove the old. Facets.Add(ab); Facets.Add(bc); Facets.Add(ca); Facets.Remove(old); // Check for 1st order flipping. // Triangle ab has neighbor ab.AB. // Depth of up to recursion deep. // Remember that due to commutators, same.same is outward, // same.different is inward. flipIfNeeded(ab, ab.AB, Recursion); flipIfNeeded(bc, bc.BC, Recursion); flipIfNeeded(ca, ca.CA, Recursion); return; }
/// <summary> /// Setup. /// </summary> /// <param name="bounds"></param> public void Setup(Rect bounds) { Triangle.ResetIndex(); Facets.Clear(); Points.Clear(); Bounds = bounds; Vertex tl = new Vertex(Bounds.xMin, Bounds.yMin, 0); Vertex tr = new Vertex(Bounds.xMax, Bounds.yMin, 0); Vertex bl = new Vertex(Bounds.xMin, Bounds.yMax, 0); Vertex br = new Vertex(Bounds.xMax, Bounds.yMax, 0); Triangle t1 = new Triangle(); Triangle t2 = new Triangle(); t1.A = bl; t1.B = tr; t1.C = tl; t2.A = bl; t2.B = br; t2.C = tr; t1.AB = t2; t2.CA = t1; Facets.Add(t1); Facets.Add(t2); }
/// <summary> /// Append point. /// </summary> /// <param name="v"></param> public void Append(Vertex v) { // Find a triangle containing v. for (int i = 0; i < Facets.Count; i++) { if (Facets[i].Contains(v)) { Insert(v, Facets[i]); } } }
/// <summary> /// The distance between this and t. /// </summary> /// <param name="t"></param> /// <returns></returns> public float Distance(Vertex t) { return (float)System.Math.Sqrt(DeltaSquared(t)); }
/// <summary> /// Delta distance squared between this and other vertex t /// </summary> /// <param name="t"></param> /// <returns></returns> public float DeltaSquaredXY(Vertex t) { float dx = (X - t.X); float dy = (Y - t.Y); return (dx * dx) + (dy * dy); }