/** * Get Z value of a specific point in the triangle Take into account triangles connected to the * edge * * @param aPoint * @return ZValuei */ public final double softInterpolateZ(DPoint aPoint) { double weight = (double) PT_NB; double zValue = interpolateZ(aPoint) * weight; // Process connected edges for (int i = 0; i < PT_NB; i++) { DEdge anEdge = edges[i]; DTriangle aTriangle = null; if (anEdge != null) { if (anEdge.getLeft() == this) { aTriangle = anEdge.getRight(); } else { aTriangle = anEdge.getLeft(); } } if (aTriangle != null) { weight += 1.0; zValue += aTriangle.interpolateZ(aPoint); } } // Define new Z value zValue /= weight; return zValue; }
/** * Returns true if ed is equals to one of the edges that form this triangle. * * @param ed * @return true if ed is an edge of this. */ public final boolean isEdgeOf(DEdge ed) { for (DEdge e : edges) { if (e.equals(ed)) { return true; } } return false; }
/** * Get the edge that contains pt (if any, and the first found if pt is an apex) * * @param pt * @return The containing edge, if any, null otherwise. */ public final DEdge getContainingEdge(DPoint pt) { if (isOnAnEdge(pt)) { for (DEdge edge : edges) { if (edge.contains(pt)) { return edge; } } } return null; }
/** * Create a new triangle with three input points. * * @param p1 * @param p2 * @param p3 * @throws DelaunayError */ public DTriangle(DPoint p1, DPoint p2, DPoint p3) throws DelaunayError { super(); init(); DEdge e1 = new DEdge(p1, p2); DEdge e2 = new DEdge(p2, p3); DEdge e3 = new DEdge(p3, p1); edges[0] = e1; edges[1] = e2; edges[2] = e3; connectEdges(); computeCenter(); radius = e1.getStartPoint().squareDistance2D(xCenter, yCenter); }
/** * Compute the intersection point according the steepest vector. We assume that the point is in * the Triangle * * @param dPoint * @return DPoint * @throws DelaunayError */ public final DPoint getSteepestIntersectionPoint(DPoint dPoint) throws DelaunayError { if (isInside(dPoint)) { for (DEdge dEdge : edges) { if (isTopoOrientedToEdge(dEdge)) { DPoint pt = Tools.computeIntersection( dEdge.getStartPoint(), dEdge.getDirectionVector(), dPoint, getSteepestVector()); if (dEdge.contains(pt)) { return pt; } } } } return null; }
/** * Check if the point is an apex of the triangle * * @param aPoint * @return belongs */ public final boolean belongsTo(DPoint aPoint) { boolean belongs = false; DEdge anEdge = this.getEdge(0); if (anEdge.getStartPoint().equals(aPoint)) { belongs = true; } else if (anEdge.getEndPoint().equals(aPoint)) { belongs = true; } else { anEdge = this.getEdge(1); if (anEdge.getStartPoint().equals(aPoint)) { belongs = true; } else if (anEdge.getEndPoint().equals(aPoint)) { belongs = true; } } return belongs; }
/** * Get the edge of the triangle that includes the two point * * @param p1 * @param p2 * @return alterEdge */ protected final DEdge getEdgeFromPoints(DPoint p1, DPoint p2) { DEdge alterEdge = null; DPoint test1, test2; int i = 0; while (i < PT_NB && alterEdge == null) { DEdge testEdge = edges[i]; test1 = testEdge.getStartPoint(); test2 = testEdge.getEndPoint(); if ((test1.equals(p1)) && (test2.equals(p2))) { alterEdge = testEdge; } else if ((test1.equals(p2)) && (test2.equals(p1))) { alterEdge = testEdge; } else { i++; } } return alterEdge; }
/** * Compute the intersection point according to the vector opposite to the steepest vector. If dp * is outside the triangle, we return null. * * @param dp * @return The point pt of the triangle's boundary for which (dp pt) is colinear to the steepest * vector. * @throws DelaunayError */ public final DPoint getCounterSteepestIntersection(DPoint dp) throws DelaunayError { if (isInside(dp) || isOnAnEdge(dp)) { for (DEdge ed : edges) { if (!isTopoOrientedToEdge(ed)) { DPoint counterSteep = getSteepestVector(); counterSteep.setX(-counterSteep.getX()); counterSteep.setY(-counterSteep.getY()); counterSteep.setZ(-counterSteep.getZ()); DPoint pt = Tools.computeIntersection( ed.getStartPoint(), ed.getDirectionVector(), dp, counterSteep); if (ed.contains(pt)) { return pt; } } } } return null; }
/** * Check if the point is inside the triangle * * @param aPoint * @return isInside */ public final boolean isInside(DPoint aPoint) { boolean isInside = true; int k = 0; while ((k < PT_NB) && (isInside)) { DEdge theEdge = edges[k]; if (theEdge.getLeft() == this) { if (theEdge.isRight(aPoint)) { isInside = false; } } else { if (theEdge.isLeft(aPoint)) { isInside = false; } } k++; } return isInside; }
/** * Returns true if the triangle is turned toward the edge ed. * * @param ed * @return true if this is pouring into ed. * @throws org.jdelaunay.delaunay.error.DelaunayError */ public final boolean isTopoOrientedToEdge(DEdge ed) throws DelaunayError { // on determine les sommets A,B et C du triangle et on calle AB (ou BA) // sur e DPoint a = ed.getStartPoint(); DPoint b = ed.getEndPoint(); if (!this.belongsTo(a) || !belongsTo(b)) { throw new DelaunayError(DelaunayError.DELAUNAY_ERROR_OUTSIDE_TRIANGLE); } DPoint c = getOppositePoint(ed); DPoint ab = Tools.vectorialDiff(b, a); DPoint ac = Tools.vectorialDiff(c, a); // orientation CCW if (Tools.vectorProduct(ab, ac).getZ() < 0) { // echange A et B DPoint d = a; a = b; b = d; ab = Tools.vectorialDiff(b, a); } // test d'intersection entre AB et P DPoint p = getSteepestVector(); return Tools.vectorProduct(ab, p).getZ() < 0; }
/** * Get the last edge that form, with e1 and e2, this triangle. If e1 or e2 do not belong to this * triangle, return null. * * @param e1 * @param e2 * @return the edge of the triangle that is not e1 or e2. Null if e1 or e2 is not an edge of the * triangle. */ public final DEdge getLastEdge(DEdge e1, DEdge e2) { if (e1.equals(edges[0])) { if (e2.equals(edges[1])) { return edges[2]; } else if (e2.equals(edges[2])) { return edges[1]; } } else if (e1.equals(edges[1])) { if (e2.equals(edges[0])) { return edges[2]; } else if (e2.equals(edges[2])) { return edges[0]; } } else if (e1.equals(edges[2])) { if (e2.equals(edges[0])) { return edges[1]; } else if (e2.equals(edges[1])) { return edges[0]; } } return null; }
/** * This method force the link between this and its edges, and ensure that edges are not pointing * to duplicates of this triangle. */ public final void forceCoherenceWithEdges() { for (DEdge edg : edges) { DTriangle tri = edg.getLeft(); DTriangle tri2 = edg.getRight(); if (equals(tri)) { edg.setLeft(this); } else if (equals(tri2)) { edg.setRight(this); } else { DPoint op = getOppositePoint(edg); if (op != null) { if (edg.isLeft(op)) { edg.setLeft(this); } else { edg.setRight(this); } } } } }
/** * Create a new triangle with the three given edges as a basis. * * <p>An integrity check is processed while building the triangle. This constructor is the best * way to ensure that already existing edges will be linked to the good triangles, and that ther * won't be any edge duplication in the data structures. * * @param e1 * @param e2 * @param e3 * @throws DelaunayError If there is at least two edges that don't share exactly a point. */ public DTriangle(DEdge e1, DEdge e2, DEdge e3) throws DelaunayError { super(); init(); // We check the integrity of the edges given to build this triangle boolean integrityE1E2 = (e1.isExtremity(e2.getStartPoint()) && !e3.isExtremity((e2.getStartPoint()))) || (e1.isExtremity(e2.getEndPoint()) && !e3.isExtremity(e2.getEndPoint())); boolean integrityE1EptNb = (e1.isExtremity(e3.getStartPoint()) && !e2.isExtremity((e3.getStartPoint()))) || (e1.isExtremity(e3.getEndPoint()) && !e2.isExtremity(e3.getEndPoint())); boolean integrityEptNbE2 = (e2.isExtremity(e3.getStartPoint()) && !e1.isExtremity((e3.getStartPoint()))) || (e2.isExtremity(e3.getEndPoint()) && !e1.isExtremity(e3.getEndPoint())); if (integrityE1E2 && integrityE1EptNb && integrityEptNbE2) { edges[0] = e1; edges[1] = e2; edges[2] = e3; connectEdges(); computeCenter(); radius = e1.getStartPoint().squareDistance2D(xCenter, yCenter); } else { throw new DelaunayError( "Problem while generating the Triangle : " + integrityE1E2 + " " + integrityE1EptNb + " " + integrityEptNbE2); } }
/** * Get the point of the triangle that does not belong to the edge * * @param ed * @return alterPoint */ public final DPoint getOppositePoint(DEdge ed) { DPoint start = ed.getStartPoint(); DPoint end = ed.getEndPoint(); return getAlterPoint(start, end); }
/** * get the slope of this DTriangle, in degrees. Be careful, as the returned value will be * negative. * * @return the slope, in degrees. * @throws DelaunayError */ public final double getSlopeInDegree() throws DelaunayError { DPoint steep = getSteepestVector(); DEdge ed = new DEdge(new DPoint(0, 0, 0), steep); return ed.getSlopeInDegree(); }
/** * Common implementation for the search operations. * * @param pt * @param safe * @return * @throws DelaunayError */ private Element searchPointImpl(final DPoint pt, final boolean safe) throws DelaunayError { Element ret = null; if (contains(pt)) { return this; } else { for (DEdge ed : edges) { DPoint op = getOppositePoint(ed); if (ed.isRight(pt) && ed.isLeft(op)) { if (ed.isLocked() && safe) { return null; } else if (ed.getRight() != null) { return ed.getRight().searchPointContainer(pt); } else { ret = ed; } } else if (ed.isLeft(pt) && ed.isRight(op)) { if (ed.isLocked() && safe) { return null; } else if (ed.getLeft() != null) { return ed.getLeft().searchPointContainer(pt); } else { ret = ed; } } } } return ret; }