private static Triangle_dt find(Triangle_dt curr, Point_dt p) { if (p == null) { return(null); } Triangle_dt next_t; if (curr.halfplane) { next_t = findnext2(p, curr); if (next_t == null || next_t.halfplane) { return(curr); } curr = next_t; } while (true) { next_t = findnext1(p, curr); if (next_t == null) { return(curr); } if (next_t.halfplane) { return(next_t); } curr = next_t; } }
/* * assumes v is NOT an halfplane! * returns the next triangle for find. */ private static Triangle_dt findnext1(Point_dt p, Triangle_dt v) { if (p.pointLineTest(v.a, v.b) == Point_dt.RIGHT && !v.abnext.halfplane) { return(v.abnext); } if (p.pointLineTest(v.b, v.c) == Point_dt.RIGHT && !v.bcnext.halfplane) { return(v.bcnext); } if (p.pointLineTest(v.c, v.a) == Point_dt.RIGHT && !v.canext.halfplane) { return(v.canext); } if (p.pointLineTest(v.a, v.b) == Point_dt.RIGHT) { return(v.abnext); } if (p.pointLineTest(v.b, v.c) == Point_dt.RIGHT) { return(v.bcnext); } if (p.pointLineTest(v.c, v.a) == Point_dt.RIGHT) { return(v.canext); } return(null); }
private Triangle_dt extendInside(Triangle_dt t, Point_dt p) { Triangle_dt h1, h2; h1 = treatDegeneracyInside(t, p); if (h1 != null) { return(h1); } h1 = new Triangle_dt(t.c, t.a, p); h2 = new Triangle_dt(t.b, t.c, p); t.c = p; t.circumcircle(); h1.abnext = t.canext; h1.bcnext = t; h1.canext = h2; h2.abnext = t.bcnext; h2.bcnext = h1; h2.canext = t; h1.abnext.switchneighbors(t, h1); h2.abnext.switchneighbors(t, h2); t.bcnext = h2; t.canext = h1; return(t); }
private Triangle_dt extendOutside(Triangle_dt t, Point_dt p) { if (p.pointLineTest(t.a, t.b) == Point_dt.ONSEGMENT) { Triangle_dt dg = new Triangle_dt(t.a, t.b, p); Triangle_dt hp = new Triangle_dt(p, t.b); t.b = p; dg.abnext = t.abnext; dg.abnext.switchneighbors(t, dg); dg.bcnext = hp; hp.abnext = dg; dg.canext = t; t.abnext = dg; hp.bcnext = t.bcnext; hp.bcnext.canext = hp; hp.canext = t; t.bcnext = hp; return(dg); } Triangle_dt ccT = extendcounterclock(t, p); Triangle_dt cT = extendclock(t, p); ccT.bcnext = cT; cT.canext = ccT; startTriangleHull = cT; return(cT.abnext); }
/** * returns an iterator to the set of all the points on the XY-convex hull * @return iterator to the set of all the points on the XY-convex hull. */ public List <Point_dt> CH_vertices_Iterator() { List <Point_dt> ans = new List <Point_dt>(); Triangle_dt curr = this.startTriangleHull; bool cont = true; double x0 = _bb_min.x, x1 = _bb_max.x; double y0 = _bb_min.y, y1 = _bb_max.y; bool sx, sy; while (cont) { sx = curr.p1().x == x0 || curr.p1().x == x1; sy = curr.p1().y == y0 || curr.p1().y == y1; if ((sx & sy) | (!sx & !sy)) { ans.Add(curr.p1()); } if (curr.bcnext != null && curr.bcnext.halfplane) { curr = curr.bcnext; } if (curr == this.startTriangleHull) { cont = false; } } return(ans); }
/** * * @param x * - X cordination of the query point * @param y * - Y cordination of the query point * @return the q point with updated Z value (z value is as given the * triangulation). */ public double z(double x, double y) { Point_dt q = new Point_dt(x, y); Triangle_dt t = find(q); return(t.z_value(q)); }
static void DoMemoryTest() { int i = 0; try { Point_dt p1 = new Point_dt(1, 1); Point_dt p3 = new Point_dt(1, 0); Point_dt p2 = new Point_dt(0, 0); List<Triangle_dt> vec = new List<Triangle_dt>(); while (true) { Triangle_dt t = new Triangle_dt(p1, p2, p3); vec.Add(t); i++; if (i % 10000 == 0) Console.WriteLine(i); } } catch (OutOfMemoryException oome) { Console.WriteLine("out of MEMORY: points: " + i); } catch (Exception e) { Console.WriteLine("out of MEMORY: points: " + i); } }
private void startTriangulation(Point_dt p1, Point_dt p2) { Point_dt ps, pb; if (p1.isLess(p2)) { ps = p1; pb = p2; } else { ps = p2; pb = p1; } firstT = new Triangle_dt(pb, ps); lastT = firstT; Triangle_dt t = new Triangle_dt(ps, pb); firstT.abnext = t; t.abnext = firstT; firstT.bcnext = t; t.canext = firstT; firstT.canext = t; t.bcnext = firstT; firstP = firstT.b; lastP = lastT.a; startTriangleHull = firstT; }
private void allTriangles(Triangle_dt curr, List <Triangle_dt> front, int mc) { if (curr != null && curr._mc == mc && !front.Contains <Triangle_dt>(curr)) { front.Add(curr); allTriangles(curr.abnext, front, mc); allTriangles(curr.bcnext, front, mc); allTriangles(curr.canext, front, mc); } }
/** * finds the triangle the query point falls in, note if out-side of this * triangulation a half plane triangle will be returned (see contains). the * search starts from the the start triangle * * @param p * query point * @param start * the triangle the search starts at. * @return the triangle that point p is in.. */ public Triangle_dt find(Point_dt p, Triangle_dt start) { if (start == null) { start = this.startTriangle; } Triangle_dt T = find(start, p); return(T); }
private Triangle_dt insertPointSimple(Point_dt p) { nPoints++; if (!allCollinear) { Triangle_dt t = find(startTriangle, p); if (t.halfplane) { startTriangle = extendOutside(t, p); } else { startTriangle = extendInside(t, p); } return(startTriangle); } if (nPoints == 1) { firstP = p; return(null); } if (nPoints == 2) { startTriangulation(firstP, p); return(null); } switch (p.pointLineTest(firstP, lastP)) { case Point_dt.LEFT: startTriangle = extendOutside(firstT.abnext, p); allCollinear = false; break; case Point_dt.RIGHT: startTriangle = extendOutside(firstT, p); allCollinear = false; break; case Point_dt.ONSEGMENT: insertCollinear(p, Point_dt.ONSEGMENT); break; case Point_dt.INFRONTOFA: insertCollinear(p, Point_dt.INFRONTOFA); break; case Point_dt.BEHINDB: insertCollinear(p, Point_dt.BEHINDB); break; } return(null); }
/** * returns an iterator object involved in the last update. * @return iterator to all triangles involved in the last update of the * triangulation NOTE: works ONLY if the are triangles (it there is * only a half plane - returns an empty iterator */ public List <Triangle_dt> getLastUpdatedTriangles() { List <Triangle_dt> tmp = new List <Triangle_dt>(); if (this.trianglesSize() > 1) { Triangle_dt t = currT; allTriangles(t, tmp, this._modCount); } return(tmp); }
public object Clone() { Triangle_dt cloned = new Triangle_dt(a,b,c); cloned._mark = _mark; cloned._mc = _mc; cloned.abnext = abnext; cloned.bcnext = bcnext; cloned.canext = canext; cloned.halfplane = halfplane; cloned.canext = canext; cloned.circum = circum; return cloned; }
public object Clone() { Triangle_dt cloned = new Triangle_dt(a, b, c); cloned._mark = _mark; cloned._mc = _mc; cloned.abnext = abnext; cloned.bcnext = bcnext; cloned.canext = canext; cloned.halfplane = halfplane; cloned.canext = canext; cloned.circum = circum; return(cloned); }
private void flip(Triangle_dt t, int mc) { var bkpT = (Triangle_dt)t.Clone(); Triangle_dt u = t.abnext, v; t._mc = mc; if (u.halfplane || !u.circumcircle_contains(t.c)) { return; } if (t.a == u.a) { v = new Triangle_dt(u.b, t.b, t.c); v.abnext = u.bcnext; t.abnext = u.abnext; } else if (t.a == u.b) { v = new Triangle_dt(u.c, t.b, t.c); v.abnext = u.canext; t.abnext = u.bcnext; } else if (t.a == u.c) { v = new Triangle_dt(u.a, t.b, t.c); v.abnext = u.abnext; t.abnext = u.canext; } else { throw new Exception("Error in flip."); } v._mc = mc; v.bcnext = t.bcnext; v.abnext.switchneighbors(u, v); v.bcnext.switchneighbors(t, v); t.bcnext = v; v.canext = t; t.b = v.a; t.abnext.switchneighbors(u, t); t.circumcircle(); currT = v; flip(t, mc); flip(v, mc); }
/** assumes v is an halfplane! - returns another (none halfplane) triangle */ private static Triangle_dt findnext2(Point_dt p, Triangle_dt v) { if (v.abnext != null && !v.abnext.halfplane) { return(v.abnext); } if (v.bcnext != null && !v.bcnext.halfplane) { return(v.bcnext); } if (v.canext != null && !v.canext.halfplane) { return(v.canext); } return(null); }
private Triangle_dt treatDegeneracyInside(Triangle_dt t, Point_dt p) { if (t.abnext.halfplane && p.pointLineTest(t.b, t.a) == Point_dt.ONSEGMENT) { return(extendOutside(t.abnext, p)); } if (t.bcnext.halfplane && p.pointLineTest(t.c, t.b) == Point_dt.ONSEGMENT) { return(extendOutside(t.bcnext, p)); } if (t.canext.halfplane && p.pointLineTest(t.a, t.c) == Point_dt.ONSEGMENT) { return(extendOutside(t.canext, p)); } return(null); }
private Triangle_dt extendclock(Triangle_dt t, Point_dt p) { t.halfplane = false; t.c = p; t.circumcircle(); Triangle_dt tbc = t.bcnext; if (p.pointLineTest(tbc.a, tbc.b) >= Point_dt.RIGHT) { Triangle_dt nT = new Triangle_dt(p, t.b); nT.abnext = t; t.bcnext = nT; nT.bcnext = tbc; tbc.canext = nT; return(nT); } return(extendclock(tbc, p)); }
private Triangle_dt extendcounterclock(Triangle_dt t, Point_dt p) { t.halfplane = false; t.c = p; t.circumcircle(); Triangle_dt tca = t.canext; if (p.pointLineTest(tca.a, tca.b) >= Point_dt.RIGHT) { Triangle_dt nT = new Triangle_dt(t.a, p); nT.abnext = t; t.canext = nT; nT.canext = tca; tca.bcnext = nT; return(nT); } return(extendcounterclock(tca, p)); }
internal void switchneighbors(Triangle_dt Old, Triangle_dt New) { if (abnext == Old) { abnext = New; } else if (bcnext == Old) { bcnext = New; } else if (canext == Old) { canext = New; } else { Console.WriteLine("Error, switchneighbors can't find Old."); } }
private void initTriangles() { if (_modCount == _modCount2) { return; } if (this.size() > 2) { _modCount2 = _modCount; List <Triangle_dt> front = new List <Triangle_dt>(); _triangles = new List <Triangle_dt>(); front.Add(this.startTriangle); while (front.Count > 0) { Triangle_dt t = front.ElementAt(0); front.RemoveAt(0); if (t._mark == false) { t._mark = true; _triangles.Add(t); if (t.abnext != null && !t.abnext._mark) { front.Add(t.abnext); } if (t.bcnext != null && !t.bcnext._mark) { front.Add(t.bcnext); } if (t.canext != null && !t.canext._mark) { front.Add(t.canext); } } } // _triNum = _triangles.size(); for (int i = 0; i < _triangles.Count; i++) { _triangles.ElementAt <Triangle_dt>(i)._mark = false; } } }
/** * insert the point to this Delaunay Triangulation. Note: if p is null or * already exist in this triangulation p is ignored. * * @param p * new vertex to be inserted the triangulation. */ public void insertPoint(Point_dt p) { if (this._vertices.Contains <Point_dt>(p)) { return; } _modCount++; updateBoundingBox(p); this._vertices.Add(p); Triangle_dt t = insertPointSimple(p); if (t == null) // { return; } Triangle_dt tt = t; currT = t; // recall the last point for - fast (last) update iterator. do { flip(tt, _modCount); tt = tt.canext; } while (tt != t && !tt.halfplane); }
void drawTriangleTopoLines(Graphics g, Triangle_dt t, double dz, Color cl) { if (t.p1().z < 0 | t.p2().z < 0 | t.p3().z < 0) return; Point_dt[] p12 = computePoints(t.p1(), t.p2(), dz); Point_dt[] p23 = computePoints(t.p2(), t.p3(), dz); Point_dt[] p31 = computePoints(t.p3(), t.p1(), dz); int i12 = 0, i23 = 0, i31 = 0; bool cont = true; while (cont) { cont = false; if (i12 < p12.Length && i23 < p23.Length && p12[i12].z == p23[i23].z) { if (p12[i12].z % 200 > 100) drawLine(g, p12[i12], p23[i23], Color.Red); else drawLine(g, p12[i12], p23[i23], Color.Yellow); i12++; i23++; cont = true; } if (i23 < p23.Length && i31 < p31.Length && p23[i23].z == p31[i31].z) { if (p23[i23].z % 200 > 100) drawLine(g, p23[i23], p31[i31], Color.Red); else drawLine(g, p23[i23], p31[i31], Color.Yellow); i23++; i31++; cont = true; } if (i12 < p12.Length && i31 < p31.Length && p12[i12].z == p31[i31].z) { if (p12[i12].z % 200 > 100) drawLine(g, p12[i12], p31[i31], Color.Red); else drawLine(g, p12[i12], p31[i31], Color.Yellow); i12++; i31++; cont = true; } } }
void MainForm_Click(object sender, MouseEventArgs e) { int xx = e.X; int yy = e.Y; switch (_stage) { case 0: { Console.WriteLine("[" + xx + "," + yy + "]"); break; } case POINT: { Point_dt q = new Point_dt(xx, yy); Point_dt p = screen2world(q); _ajd.insertPoint(p); Refresh(); break; } case FIND: { Point_dt q = new Point_dt(xx, yy); Point_dt p = screen2world(q); //_t1 = _ajd.find(p); _t1 = _ajd.FastFind(p); Refresh(); break; } case SECTION1: { Point_dt q = new Point_dt(xx, yy); _p1 = screen2world(q); // _p1 = new Point_dt(99792.03,1073355.0,30.0); // _t1 = _ajd.find(_p1); _stage = SECTION2; break; } case SECTION2: { Point_dt q = new Point_dt(xx, yy); _p2 = screen2world(q); // _p2 = new Point_dt(149587.055,1040477.0,5.0); // _t2 = _ajd.find(_p2); _los = new Visibility(_ajd); _los.computeSection(_p1, _p2); Refresh(); _stage = SECTION1; break; } case GUARD: { Point_dt q = new Point_dt(xx, yy); _p1 = screen2world(q); if (_guards == null) _guards = new List<Point_dt>(); _guards.Add(new Point_dt(_p1.x, _p1.y, GH)); /* * if(_p2!=null) { _los = new Visibility(_ajd); * _los.computeSection(_p1,_p2); _visible = * _los.isVisible(30,5); } */ Refresh(); break; } case CLIENT: { Point_dt q = new Point_dt(xx, yy); _p2 = screen2world(q); if (_clients == null) _clients = new List<Point_dt>(); _clients.Add(new Point_dt(_p2.x, _p2.y, CH)); /* * if(_p1!=null) { _los = new Visibility(_ajd); * _los.computeSection(_p1,_p2); _visible = * _los.isVisible(30,5); } */ Refresh(); break; } } }
private void allTriangles(Triangle_dt curr, List<Triangle_dt> front, int mc) { if (curr != null && curr._mc == mc && !front.Contains<Triangle_dt>(curr)) { front.Add(curr); allTriangles(curr.abnext, front, mc); allTriangles(curr.bcnext, front, mc); allTriangles(curr.canext, front, mc); } }
/* * assumes v is NOT an halfplane! * returns the next triangle for find. */ private static Triangle_dt findnext1(Point_dt p, Triangle_dt v) { if (p.pointLineTest(v.a, v.b) == Point_dt.RIGHT && !v.abnext.halfplane) return v.abnext; if (p.pointLineTest(v.b, v.c) == Point_dt.RIGHT && !v.bcnext.halfplane) return v.bcnext; if (p.pointLineTest(v.c, v.a) == Point_dt.RIGHT && !v.canext.halfplane) return v.canext; if (p.pointLineTest(v.a, v.b) == Point_dt.RIGHT) return v.abnext; if (p.pointLineTest(v.b, v.c) == Point_dt.RIGHT) return v.bcnext; if (p.pointLineTest(v.c, v.a) == Point_dt.RIGHT) return v.canext; return null; }
/** * finds the triangle the query point falls in, note if out-side of this * triangulation a half plane triangle will be returned (see contains). the * search starts from the the start triangle * * @param p * query point * @param start * the triangle the search starts at. * @return the triangle that point p is in.. */ public Triangle_dt find(Point_dt p, Triangle_dt start) { if (start == null) start = this.startTriangle; Triangle_dt T = find(start, p); return T; }
private void insertCollinear(Point_dt p, int res) { Triangle_dt t, tp, u; switch (res) { case Point_dt.INFRONTOFA: t = new Triangle_dt(firstP, p); tp = new Triangle_dt(p, firstP); t.abnext = tp; tp.abnext = t; t.bcnext = tp; tp.canext = t; t.canext = firstT; firstT.bcnext = t; tp.bcnext = firstT.abnext; firstT.abnext.canext = tp; firstT = t; firstP = p; break; case Point_dt.BEHINDB: t = new Triangle_dt(p, lastP); tp = new Triangle_dt(lastP, p); t.abnext = tp; tp.abnext = t; t.bcnext = lastT; lastT.canext = t; t.canext = tp; tp.bcnext = t; tp.canext = lastT.abnext; lastT.abnext.bcnext = tp; lastT = t; lastP = p; break; case Point_dt.ONSEGMENT: u = firstT; while (p.isGreater(u.a)) u = u.canext; t = new Triangle_dt(p, u.b); tp = new Triangle_dt(u.b, p); u.b = p; u.abnext.a = p; t.abnext = tp; tp.abnext = t; t.bcnext = u.bcnext; u.bcnext.canext = t; t.canext = u; u.bcnext = t; tp.canext = u.abnext.canext; u.abnext.canext.bcnext = tp; tp.bcnext = u.abnext; u.abnext.canext = tp; if (firstT == u) { firstT = t; } break; } }
private Triangle_dt extendOutside(Triangle_dt t, Point_dt p) { if (p.pointLineTest(t.a, t.b) == Point_dt.ONSEGMENT) { Triangle_dt dg = new Triangle_dt(t.a, t.b, p); Triangle_dt hp = new Triangle_dt(p, t.b); t.b = p; dg.abnext = t.abnext; dg.abnext.switchneighbors(t, dg); dg.bcnext = hp; hp.abnext = dg; dg.canext = t; t.abnext = dg; hp.bcnext = t.bcnext; hp.bcnext.canext = hp; hp.canext = t; t.bcnext = hp; return dg; } Triangle_dt ccT = extendcounterclock(t, p); Triangle_dt cT = extendclock(t, p); ccT.bcnext = cT; cT.canext = ccT; startTriangleHull = cT; return cT.abnext; }
private Triangle_dt extendcounterclock(Triangle_dt t, Point_dt p) { t.halfplane = false; t.c = p; t.circumcircle(); Triangle_dt tca = t.canext; if (p.pointLineTest(tca.a, tca.b) >= Point_dt.RIGHT) { Triangle_dt nT = new Triangle_dt(t.a, p); nT.abnext = t; t.canext = nT; nT.canext = tca; tca.bcnext = nT; return nT; } return extendcounterclock(tca, p); }
public void drawTriangle(Graphics g, Triangle_dt t, Color cl) { if (_view_flag == VIEW1 || t.isHalfplane()) { if (t.isHalfplane()) { if (cl == Color.Empty) drawLine(g, t.p1(), t.p2(), Color.Blue); else drawLine(g, t.p1(), t.p2(), cl); } else { if (cl == Color.Empty) { drawLine(g, t.p1(), t.p2(), Color.Black); drawLine(g, t.p2(), t.p3(), Color.Black); drawLine(g, t.p3(), t.p1(), Color.Black); } { drawLine(g, t.p1(), t.p2(), cl); drawLine(g, t.p2(), t.p3(), cl); drawLine(g, t.p3(), t.p1(), cl); } } } else { // ////////////////////////////////////////////////////////////////// double maxZ = _ajd.maxBoundingBox().z; double minZ = _ajd.minBoundingBox().z; double z = (t.p1().z + t.p2().z + t.p3().z) / 3.0; double dz = maxZ - minZ; if (dz == 0) dz = 1; int co = 30 + (int)(220 * ((z - minZ) / dz)); if (cl == Color.Empty) cl = Color.FromArgb(co, co, co); int[] xx = new int[3], yy = new int[3]; // double f = 0; // double dx_map = _dx_map.y- _dx_map.x; // double dy_map = _dy_map.y- _dy_map.x; // f = (t.p1().x -_dx_map.x)/dx_map; Point_dt p1 = world2screen(t.p1()); xx[0] = (int)p1.x; yy[0] = (int)p1.y; Point_dt p2 = world2screen(t.p2()); xx[1] = (int)p2.x; yy[1] = (int)p2.y; Point_dt p3 = world2screen(t.p3()); xx[2] = (int)p3.x; yy[2] = (int)p3.y; Brush b = new SolidBrush(cl); g.FillPolygon(b, ToPoints(xx, yy)); // //////////////////////////////////// } }
internal void switchneighbors(Triangle_dt Old, Triangle_dt New) { if ( abnext == Old ) abnext = New; else if ( bcnext == Old ) bcnext = New; else if ( canext == Old ) canext=New; else Console.WriteLine( "Error, switchneighbors can't find Old." ); }
private static Triangle_dt find(Triangle_dt curr, Point_dt p) { if (p == null) return null; Triangle_dt next_t; if (curr.halfplane) { next_t = findnext2(p, curr); if (next_t == null || next_t.halfplane) return curr; curr = next_t; } while (true) { next_t = findnext1(p, curr); if (next_t == null) return curr; if (next_t.halfplane) return next_t; curr = next_t; } }
/** * * @param p * query point * @return true iff p is within this triangulation (in its 2D convex hull). */ public bool contains(Point_dt p) { Triangle_dt tt = find(p); return(!tt.halfplane); }
/** assumes v is an halfplane! - returns another (none halfplane) triangle */ private static Triangle_dt findnext2(Point_dt p, Triangle_dt v) { if (v.abnext != null && !v.abnext.halfplane) return v.abnext; if (v.bcnext != null && !v.bcnext.halfplane) return v.bcnext; if (v.canext != null && !v.canext.halfplane) return v.canext; return null; }
/** * * @param q * Query point * @return the q point with updated Z value (z value is as given the * triangulation). */ public Point_dt z(Point_dt q) { Triangle_dt t = find(q); return(t.z(q)); }
private Triangle_dt extendclock(Triangle_dt t, Point_dt p) { t.halfplane = false; t.c = p; t.circumcircle(); Triangle_dt tbc = t.bcnext; if (p.pointLineTest(tbc.a, tbc.b) >= Point_dt.RIGHT) { Triangle_dt nT = new Triangle_dt(p, t.b); nT.abnext = t; t.bcnext = nT; nT.bcnext = tbc; tbc.canext = nT; return nT; } return extendclock(tbc, p); }
private void insertCollinear(Point_dt p, int res) { Triangle_dt t, tp, u; switch (res) { case Point_dt.INFRONTOFA: t = new Triangle_dt(firstP, p); tp = new Triangle_dt(p, firstP); t.abnext = tp; tp.abnext = t; t.bcnext = tp; tp.canext = t; t.canext = firstT; firstT.bcnext = t; tp.bcnext = firstT.abnext; firstT.abnext.canext = tp; firstT = t; firstP = p; break; case Point_dt.BEHINDB: t = new Triangle_dt(p, lastP); tp = new Triangle_dt(lastP, p); t.abnext = tp; tp.abnext = t; t.bcnext = lastT; lastT.canext = t; t.canext = tp; tp.bcnext = t; tp.canext = lastT.abnext; lastT.abnext.bcnext = tp; lastT = t; lastP = p; break; case Point_dt.ONSEGMENT: u = firstT; while (p.isGreater(u.a)) { u = u.canext; } t = new Triangle_dt(p, u.b); tp = new Triangle_dt(u.b, p); u.b = p; u.abnext.a = p; t.abnext = tp; tp.abnext = t; t.bcnext = u.bcnext; u.bcnext.canext = t; t.canext = u; u.bcnext = t; tp.canext = u.abnext.canext; u.abnext.canext.bcnext = tp; tp.bcnext = u.abnext; u.abnext.canext = tp; if (firstT == u) { firstT = t; } break; } }
private Triangle_dt extendInside(Triangle_dt t, Point_dt p) { Triangle_dt h1, h2; h1 = treatDegeneracyInside(t, p); if (h1 != null) return h1; h1 = new Triangle_dt(t.c, t.a, p); h2 = new Triangle_dt(t.b, t.c, p); t.c = p; t.circumcircle(); h1.abnext = t.canext; h1.bcnext = t; h1.canext = h2; h2.abnext = t.bcnext; h2.bcnext = h1; h2.canext = t; h1.abnext.switchneighbors(t, h1); h2.abnext.switchneighbors(t, h2); t.bcnext = h2; t.canext = h1; return t; }
private void flip(Triangle_dt t, int mc) { var bkpT = (Triangle_dt) t.Clone(); Triangle_dt u = t.abnext, v; t._mc = mc; if (u.halfplane || !u.circumcircle_contains(t.c)) return; if (t.a == u.a) { v = new Triangle_dt(u.b, t.b, t.c); v.abnext = u.bcnext; t.abnext = u.abnext; } else if (t.a == u.b) { v = new Triangle_dt(u.c, t.b, t.c); v.abnext = u.canext; t.abnext = u.bcnext; } else if (t.a == u.c) { v = new Triangle_dt(u.a, t.b, t.c); v.abnext = u.abnext; t.abnext = u.canext; } else { throw new Exception("Error in flip."); } v._mc = mc; v.bcnext = t.bcnext; v.abnext.switchneighbors(u, v); v.bcnext.switchneighbors(t, v); t.bcnext = v; v.canext = t; t.b = v.a; t.abnext.switchneighbors(u, t); t.circumcircle(); currT = v; flip(t, mc); flip(v, mc); }
/** * Add the intersections of triangle t with the section to the list of * intersection (set) */ void cut(Triangle_dt t) { if (t.isHalfplane()) return; Point_dt p1 = t.p1(), p2 = t.p2(), p3 = t.p3(); int f1 = p1.pointLineTest(_p1, _p2); int f2 = p2.pointLineTest(_p1, _p2); int f3 = p3.pointLineTest(_p1, _p2); if ((f1 == Point_dt.LEFT | f1 == Point_dt.RIGHT) && (f1 == f2 && f1 == f3)) return; if (f1 != f2 && _p1.pointLineTest(p1, p2) != _p2.pointLineTest(p1, p2)) Add(intersection(p1, p2)); if (f2 != f3 && _p1.pointLineTest(p2, p3) != _p2.pointLineTest(p2, p3)) Add(intersection(p2, p3)); if (f3 != f1 && _p1.pointLineTest(p3, p1) != _p2.pointLineTest(p3, p1)) Add(intersection(p3, p1)); }
private Triangle_dt insertPointSimple(Point_dt p) { nPoints++; if (!allCollinear) { Triangle_dt t = find(startTriangle, p); if (t.halfplane) startTriangle = extendOutside(t, p); else startTriangle = extendInside(t, p); return startTriangle; } if (nPoints == 1) { firstP = p; return null; } if (nPoints == 2) { startTriangulation(firstP, p); return null; } switch (p.pointLineTest(firstP, lastP)) { case Point_dt.LEFT: startTriangle = extendOutside(firstT.abnext, p); allCollinear = false; break; case Point_dt.RIGHT: startTriangle = extendOutside(firstT, p); allCollinear = false; break; case Point_dt.ONSEGMENT: insertCollinear(p, Point_dt.ONSEGMENT); break; case Point_dt.INFRONTOFA: insertCollinear(p, Point_dt.INFRONTOFA); break; case Point_dt.BEHINDB: insertCollinear(p, Point_dt.BEHINDB); break; } return null; }
Triangle_dt next_t(Point_dt pp1, Point_dt pp2, Triangle_dt curr, List<Triangle_dt> tr) { Triangle_dt ans = null, t12, t23, t31; t12 = curr.next_12(); t23 = curr.next_23(); t31 = curr.next_31(); if (t12 != null && cut(pp1, pp2, t12) && !tr.Contains(t12)) ans = t12; else if (t23 != null && cut(pp1, pp2, t23) && !tr.Contains(t23)) ans = t23; else if (t31 != null && cut(pp1, pp2, t31) && !tr.Contains(t31)) ans = t31; return ans; }
private Triangle_dt treatDegeneracyInside(Triangle_dt t, Point_dt p) { if (t.abnext.halfplane && p.pointLineTest(t.b, t.a) == Point_dt.ONSEGMENT) return extendOutside(t.abnext, p); if (t.bcnext.halfplane && p.pointLineTest(t.c, t.b) == Point_dt.ONSEGMENT) return extendOutside(t.bcnext, p); if (t.canext.halfplane && p.pointLineTest(t.a, t.c) == Point_dt.ONSEGMENT) return extendOutside(t.canext, p); return null; }
/** return true iff the segment _p1,_p2 is cutting t */ bool cut(Point_dt pp1, Point_dt pp2, Triangle_dt t) { bool ans = false; if (t.isHalfplane()) return false; Point_dt p1 = t.p1(), p2 = t.p2(), p3 = t.p3(); int f1 = p1.pointLineTest(pp1, pp2); int f2 = p2.pointLineTest(pp1, pp2); int f3 = p3.pointLineTest(pp1, pp2); if ((f1 == Point_dt.LEFT | f1 == Point_dt.RIGHT) && (f1 == f2 && f1 == f3)) return false; if (f1 != f2 && pp1.pointLineTest(p1, p2) != pp2.pointLineTest(p1, p2)) return true; if (f2 != f3 && pp1.pointLineTest(p2, p3) != pp2.pointLineTest(p2, p3)) return true; if (f3 != f1 && pp1.pointLineTest(p3, p1) != pp2.pointLineTest(p3, p1)) return true; return ans; }