private void flip(Triangle t, int mc) { Triangle u = t.getAbTriangle(); Triangle v; t.setMc(mc); if (u.isHalfplane() || !u.circumcircleContains(t.getC())) return; if (t.getA() == u.getA()) { v = new Triangle(u.getB(), t.getB(), t.getC()); v.setAbTriangle(u.getBcTriangle()); t.setAbTriangle(u.getAbTriangle()); } else if (t.getA() == u.getB()) { v = new Triangle(u.getC(), t.getB(), t.getC()); v.setAbTriangle(u.getCaTriangle()); t.setAbTriangle(u.getBcTriangle()); } else if (t.getA() == u.getC()) { v = new Triangle(u.getA(), t.getB(), t.getC()); v.setAbTriangle(u.getAbTriangle()); t.setAbTriangle(u.getCaTriangle()); } else { throw new RuntimeException("Error in flip."); v.setMc(mc); v.setBcTriangle(t.getBcTriangle()); v.getAbTriangle().switchneighbors(u, v); v.getBcTriangle().switchneighbors(t, v); t.setBcTriangle(v); v.setCanext(t); t.setB(v.getA()); t.getAbTriangle().switchneighbors(u, t);
/** assumes v is an halfplane! - returns another (none halfplane) triangle */ private static Triangle findnext2(Point p, Triangle v) { if (v.getAbTriangle() != null && !v.getAbTriangle().isHalfplane()) return v.getAbTriangle(); if (v.getBcTriangle() != null && !v.getBcTriangle().isHalfplane()) return v.getBcTriangle(); if (v.getCaTriangle() != null && !v.getCaTriangle().isHalfplane()) return v.getCaTriangle(); return null; }
private Triangle extendInside(Triangle t, Point p) { Triangle h1, h2; h1 = treatDegeneracyInside(t, p); if (h1 != null) return h1; h1 = new Triangle(t.getC(), t.getA(), p); h2 = new Triangle(t.getB(), t.getC(), p); t.setC(p); t.circumcircle(); h1.setAbTriangle(t.getCaTriangle()); h1.setBcTriangle(t); h1.setCanext(h2); h2.setAbTriangle(t.getBcTriangle()); h2.setBcTriangle(h1); h2.setCanext(t); h1.getAbTriangle().switchneighbors(t, h1); h2.getAbTriangle().switchneighbors(t, h2); t.setBcTriangle(h2); t.setCanext(h1); return t; }
private Triangle extendcounterclock(Triangle t, Point p) { t.setHalfplane(false); t.setC(p); t.circumcircle(); Triangle tca = t.getCaTriangle(); if (p.pointLineTest(tca.getA(), tca.getB()) >= Point.RIGHT) { Triangle nT = new Triangle(t.getA(), p); nT.setAbTriangle(t); t.setCanext(nT); nT.setCanext(tca); tca.setBcTriangle(nT); return nT; } return extendcounterclock(tca, p); }
private static Triangle findnext1(Point p, Triangle v) { if (p.pointLineTest(v.getA(), v.getB()) == Point.RIGHT && !v.getAbTriangle().isHalfplane()) return v.getAbTriangle(); if (p.pointLineTest(v.getB(), v.getC()) == Point.RIGHT && !v.getBcTriangle().isHalfplane()) return v.getBcTriangle(); if (p.pointLineTest(v.getC(), v.getA()) == Point.RIGHT && !v.getCaTriangle().isHalfplane()) return v.getCaTriangle(); if (p.pointLineTest(v.getA(), v.getB()) == Point.RIGHT) return v.getAbTriangle(); if (p.pointLineTest(v.getB(), v.getC()) == Point.RIGHT) return v.getBcTriangle(); if (p.pointLineTest(v.getC(), v.getA()) == Point.RIGHT) return v.getCaTriangle(); return null; }
t = new Triangle(firstP, p); tp = new Triangle(p, firstP); t.setAbTriangle(tp); tp.setAbTriangle(t); t.setBcTriangle(tp); tp.setCanext(t); t.setCanext(firstT); firstT.setBcTriangle(t); tp.setBcTriangle(firstT.getAbTriangle()); firstT.getAbTriangle().setCanext(tp); firstT = t; firstP = p; break; case Point.BEHINDB: t = new Triangle(p, lastP); tp = new Triangle(lastP, p); t.setAbTriangle(tp); tp.setAbTriangle(t); t.setBcTriangle(lastT); lastT.setCanext(t); t.setCanext(tp); tp.setBcTriangle(t); tp.setCanext(lastT.getAbTriangle()); lastT.getAbTriangle().setBcTriangle(tp); lastT = t; lastP = p; case Point.ONSEGMENT: u = firstT;
private Triangle extendOutside(Triangle t, Point p) { if (p.pointLineTest(t.getA(), t.getB()) == Point.ONSEGMENT) { Triangle dg = new Triangle(t.getA(), t.getB(), p); Triangle hp = new Triangle(p, t.getB()); t.setB(p); dg.setAbTriangle(t.getAbTriangle()); dg.getAbTriangle().switchneighbors(t, dg); dg.setBcTriangle(hp); hp.setAbTriangle(dg); dg.setCanext(t); t.setAbTriangle(dg); hp.setBcTriangle(t.getBcTriangle()); hp.getBcTriangle().setCanext(hp); hp.setCanext(t); t.setBcTriangle(hp); return dg; } Triangle ccT = extendcounterclock(t, p); Triangle cT = extendclock(t, p); ccT.setBcTriangle(cT); cT.setCanext(ccT); startTriangleHull = cT; return cT.getAbTriangle(); }
private void updateNeighbor(Triangle addedTriangle, Triangle deletedTriangle, Point pointToDelete) { Point delA = deletedTriangle.getA(); Point delB = deletedTriangle.getB(); Point delC = deletedTriangle.getC(); Point addA = addedTriangle.getA(); Point addB = addedTriangle.getB(); Point addC = addedTriangle.getC(); deletedTriangle.getBcTriangle().switchneighbors(deletedTriangle, addedTriangle); addedTriangle.setAbTriangle(deletedTriangle.getBcTriangle()); addedTriangle.setCanext(deletedTriangle.getBcTriangle()); addedTriangle.setBcTriangle(deletedTriangle.getBcTriangle()); deletedTriangle.getCaTriangle().switchneighbors(deletedTriangle, addedTriangle); addedTriangle.setAbTriangle(deletedTriangle.getCaTriangle()); addedTriangle.setCanext(deletedTriangle.getCaTriangle()); addedTriangle.setBcTriangle(deletedTriangle.getCaTriangle()); deletedTriangle.getAbTriangle().switchneighbors(deletedTriangle, addedTriangle); addedTriangle.setAbTriangle(deletedTriangle.getAbTriangle()); addedTriangle.setCanext(deletedTriangle.getAbTriangle());
public static void exportSmf(List<Triangle> triangulation, Writer writer) { Set<Point> pointSet = new HashSet<Point>(); for (Triangle t : triangulation) { if (!t.isHalfplane()) { pointSet.add(t.getA()); pointSet.add(t.getB()); pointSet.add(t.getC()); if (!t.isHalfplane()) { Integer i1 = pointMap.get(t.getA()); Integer i2 = pointMap.get(t.getB()); Integer i3 = pointMap.get(t.getC()); if (i1 == null || i2 == null || i3 == null) throw new RuntimeException("wrong triangulation inner bug - cant write as an SMF file!");
private void startTriangulation(Point p1, Point p2) { Point ps, pb; if (p1.isLess(p2)) { ps = p1; pb = p2; } else { ps = p2; pb = p1; } firstT = new Triangle(pb, ps); lastT = firstT; Triangle t = new Triangle(ps, pb); firstT.setAbTriangle(t); t.setAbTriangle(firstT); firstT.setBcTriangle(t); t.setCanext(firstT); firstT.setCanext(t); t.setBcTriangle(firstT); firstP = firstT.getB(); lastP = lastT.getA(); startTriangleHull = firstT; }
private Point findDiagonal(Triangle triangle, Point point) { Point p1 = triangle.getA(); Point p2 = triangle.getB(); Point p3 = triangle.getC(); if ((p1.pointLineTest(point, p3) == Point.LEFT) && (p2.pointLineTest(point, p3) == Point.RIGHT)) return p3; if ((p3.pointLineTest(point, p2) == Point.LEFT) && (p1.pointLineTest(point, p2) == Point.RIGHT)) return p2; if ((p2.pointLineTest(point, p1) == Point.LEFT) && (p3.pointLineTest(point, p1) == Point.RIGHT)) return p1; return null; }
private void updateNeighbor(Triangle addedTriangle1, Triangle addedTriangle2) { Point A1 = addedTriangle1.getA(); Point B1 = addedTriangle1.getB(); Point C1 = addedTriangle1.getC(); Point A2 = addedTriangle2.getA(); Point B2 = addedTriangle2.getB(); Point C2 = addedTriangle2.getC(); addedTriangle1.setAbTriangle(addedTriangle2); addedTriangle2.setAbTriangle(addedTriangle1); addedTriangle1.setAbTriangle(addedTriangle2); addedTriangle2.setCanext(addedTriangle1); addedTriangle1.setCanext(addedTriangle2); addedTriangle2.setAbTriangle(addedTriangle1); addedTriangle1.setCanext(addedTriangle2); addedTriangle2.setCanext(addedTriangle1); addedTriangle1.setAbTriangle(addedTriangle2); addedTriangle2.setAbTriangle(addedTriangle1); addedTriangle1.setAbTriangle(addedTriangle2); addedTriangle2.setBcTriangle(addedTriangle1); addedTriangle1.setCanext(addedTriangle2); addedTriangle2.setAbTriangle(addedTriangle1); addedTriangle1.setCanext(addedTriangle2);
public boolean fallInsideCircumcircle(Point[] arrayPoints) { boolean isInside = false; Point p1 = this.getA(); Point p2 = this.getB(); Point p3 = this.getC(); int i = 0; while (!isInside && i < arrayPoints.length) { Point p = arrayPoints[i]; if (!p.equals(p1) && !p.equals(p2) && !p.equals(p3)) { isInside = this.circumcircleContains(p); } i++; } return isInside; }
/** * 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 Iterator<Point> getConvexHullVerticesIterator() { Vector<Point> ans = new Vector<Point>(); Triangle curr = this.startTriangleHull; boolean cont = true; double x0 = bbMin.getX(), x1 = bbMax.getX(); double y0 = bbMin.getY(), y1 = bbMax.getY(); boolean sx, sy; while (cont) { sx = curr.getA().getX() == x0 || curr.getA().getX() == x1; sy = curr.getA().getY() == y0 || curr.getA().getY() == y1; if ((sx && sy) || (!sx && !sy)) { ans.add(curr.getA()); } if (curr.getBcTriangle() != null && curr.getBcTriangle().isHalfplane()) curr = curr.getBcTriangle(); if (curr == this.startTriangleHull) cont = false; } return ans.iterator(); }
return new Triangle(arrayPoints[0], arrayPoints[1], arrayPoints[2]); } else { for (int i = 0; i <= size - 1; i++) { Point p3 = arrayPoints[k]; Triangle t = new Triangle(p1, p2, p3); if ((calcDet(p1, p2, p3) >= 0) && !t.contains(p)) { if (!t.fallInsideCircumcircle(arrayPoints)) return t; if (size == 4 && (calcDet(p1, p2, p3) >= 0) && !t.containsBoundaryIsOutside(p)) { if (!t.fallInsideCircumcircle(arrayPoints)) return t;
/** * * @param p * query point * @return true iff p is within this triangulation (in its 2D convex hull). */ public boolean contains(Point p) { Triangle tt = find(p); return !tt.isHalfplane(); }
public Vector<Triangle> findTriangleNeighborhood(Triangle firstTriangle, Point point) { Vector<Triangle> triangles = new Vector<Triangle>(30); triangles.add(firstTriangle); Triangle prevTriangle = null; Triangle currentTriangle = firstTriangle; Triangle nextTriangle = currentTriangle.nextNeighbor(point, prevTriangle); while (nextTriangle != firstTriangle) { // the point is on the perimeter if (nextTriangle.isHalfplane()) { return null; } triangles.add(nextTriangle); prevTriangle = currentTriangle; currentTriangle = nextTriangle; nextTriangle = currentTriangle.nextNeighbor(point, prevTriangle); } return triangles; }
/** * 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 p) { if (vertices.contains(p)) return; modCount++; updateBoundingBox(p); vertices.add(p); Triangle t = insertPointSimple(p); if (t == null) // return; Triangle tt = t; currT = t; // recall the last point for - fast (last) update iterator. do { flip(tt, modCount); tt = tt.getCaTriangle(); } while (tt != t && !tt.isHalfplane()); // Update index with changed triangles if (gridIndex != null) gridIndex.updateIndex(getLastUpdatedTriangles()); }
if (t.isHalfplane()) startTriangle = extendOutside(t, p); else startTriangle = extendOutside(firstT.getAbTriangle(), p); allCollinear = false; break;