private void computeCentre() { switch (this.extremalPts.length) { case 0: this.centre = null; break; case 1: this.centre = this.extremalPts[0]; break; case 2: this.centre = new Coordinate( (this.extremalPts[0].x + this.extremalPts[1].x) / 2.0, (this.extremalPts[0].y + this.extremalPts[1].y) / 2.0 ); break; case 3: this.centre = Triangle.circumcentre(this.extremalPts[0], this.extremalPts[1], this.extremalPts[2]); break; } }
/** * Checks if the computed value for isInCircle is correct, using * double-double precision arithmetic. * * @param a a vertex of the triangle * @param b a vertex of the triangle * @param c a vertex of the triangle * @param p the point to test */ private static void checkRobustInCircle(Coordinate a, Coordinate b, Coordinate c, Coordinate p) { boolean nonRobustInCircle = isInCircleNonRobust(a, b, c, p); boolean isInCircleDD = TrianglePredicate.isInCircleDDSlow(a, b, c, p); boolean isInCircleCC = TrianglePredicate.isInCircleCC(a, b, c, p); Coordinate circumCentre = Triangle.circumcentre(a, b, c); System.out.println("p radius diff a = " + Math.abs(p.distance(circumCentre) - a.distance(circumCentre)) / a.distance(circumCentre)); if (nonRobustInCircle != isInCircleDD || nonRobustInCircle != isInCircleCC) { System.out.println("inCircle robustness failure (double result = " + nonRobustInCircle + ", DD result = " + isInCircleDD + ", CC result = " + isInCircleCC + ")"); System.out.println(WKTWriter.toLineString(new CoordinateArraySequence( new Coordinate[] { a, b, c, p }))); System.out.println("Circumcentre = " + WKTWriter.toPoint(circumCentre) + " radius = " + a.distance(circumCentre)); System.out.println("p radius diff a = " + Math.abs(p.distance(circumCentre) / a.distance(circumCentre) - 1)); System.out.println("p radius diff b = " + Math.abs(p.distance(circumCentre) / b.distance(circumCentre) - 1)); System.out.println("p radius diff c = " + Math.abs(p.distance(circumCentre) / c.distance(circumCentre) - 1)); System.out.println(); } }
@Override public void visit(QuadEdge[] triEdges) { Coordinate a = triEdges[0].orig().getCoordinate(); Coordinate b = triEdges[1].orig().getCoordinate(); Coordinate c = triEdges[2].orig().getCoordinate(); // TODO: choose the most accurate circumcentre based on the edges Coordinate cc = Triangle.circumcentre(a, b, c); Vertex ccVertex = new Vertex(cc); // save the circumcentre as the origin for the dual edges originating in this triangle for (int i = 0; i < 3; i++) { triEdges[i].rot().setOrig(ccVertex); } }
public void updateArea() { if (prev == null || next == null) { area = MAX_AREA; return; } area = Math.abs(Triangle.area(prev.pt, pt, next.pt)); }
/** * Checks if the computed value for isInCircle is correct, using * double-double precision arithmetic. * * @param a a vertex of the triangle * @param b a vertex of the triangle * @param c a vertex of the triangle * @param p the point to test */ private static void checkRobustInCircle(Coordinate a, Coordinate b, Coordinate c, Coordinate p) { boolean nonRobustInCircle = isInCircleNonRobust(a, b, c, p); boolean isInCircleDD = TrianglePredicate.isInCircleDDSlow(a, b, c, p); boolean isInCircleCC = TrianglePredicate.isInCircleCC(a, b, c, p); Coordinate circumCentre = Triangle.circumcentre(a, b, c); System.out.println("p radius diff a = " + Math.abs(p.distance(circumCentre) - a.distance(circumCentre)) / a.distance(circumCentre)); if (nonRobustInCircle != isInCircleDD || nonRobustInCircle != isInCircleCC) { System.out.println("inCircle robustness failure (double result = " + nonRobustInCircle + ", DD result = " + isInCircleDD + ", CC result = " + isInCircleCC + ")"); System.out.println(WKTWriter.toLineString(new CoordinateArraySequence( new Coordinate[]{a, b, c, p}))); System.out.println("Circumcentre = " + WKTWriter.toPoint(circumCentre) + " radius = " + a.distance(circumCentre)); System.out.println("p radius diff a = " + Math.abs(p.distance(circumCentre) / a.distance(circumCentre) - 1)); System.out.println("p radius diff b = " + Math.abs(p.distance(circumCentre) / b.distance(circumCentre) - 1)); System.out.println("p radius diff c = " + Math.abs(p.distance(circumCentre) / c.distance(circumCentre) - 1)); System.out.println(); } }
/** * Checks if the computed value for isInCircle is correct, using * double-double precision arithmetic. * * @param a a vertex of the triangle * @param b a vertex of the triangle * @param c a vertex of the triangle * @param p the point to test */ private static void checkRobustInCircle(Coordinate a, Coordinate b, Coordinate c, Coordinate p) { boolean nonRobustInCircle = isInCircle(a, b, c, p); boolean isInCircleDD = TriPredicate.isInCircleDD(a, b, c, p); boolean isInCircleCC = TriPredicate.isInCircleCC(a, b, c, p); Coordinate circumCentre = Triangle.circumcentre(a, b, c); System.out.println("p radius diff a = " + Math.abs(p.distance(circumCentre) - a.distance(circumCentre)) / a.distance(circumCentre)); if (nonRobustInCircle != isInCircleDD || nonRobustInCircle != isInCircleCC) { System.out.println("inCircle robustness failure (double result = " + nonRobustInCircle + ", DD result = " + isInCircleDD + ", CC result = " + isInCircleCC + ")"); System.out.println(WKTWriter.toLineString(new CoordinateArraySequence( new Coordinate[] { a, b, c, p }))); System.out.println("Circumcentre = " + WKTWriter.toPoint(circumCentre) + " radius = " + a.distance(circumCentre)); System.out.println("p radius diff a = " + Math.abs(p.distance(circumCentre)/a.distance(circumCentre) - 1)); System.out.println("p radius diff b = " + Math.abs(p.distance(circumCentre)/b.distance(circumCentre) - 1)); System.out.println("p radius diff c = " + Math.abs(p.distance(circumCentre)/c.distance(circumCentre) - 1)); System.out.println(); } }
/** * Checks if the computed value for isInCircle is correct, using * double-double precision arithmetic. * * @param a a vertex of the triangle * @param b a vertex of the triangle * @param c a vertex of the triangle * @param p the point to test */ private static void checkRobustInCircle(Coordinate a, Coordinate b, Coordinate c, Coordinate p) { boolean nonRobustInCircle = isInCircleNonRobust(a, b, c, p); boolean isInCircleDD = TrianglePredicate.isInCircleDDSlow(a, b, c, p); boolean isInCircleCC = TrianglePredicate.isInCircleCC(a, b, c, p); Coordinate circumCentre = Triangle.circumcentre(a, b, c); System.out.println("p radius diff a = " + Math.abs(p.distance(circumCentre) - a.distance(circumCentre)) / a.distance(circumCentre)); if (nonRobustInCircle != isInCircleDD || nonRobustInCircle != isInCircleCC) { System.out.println("inCircle robustness failure (double result = " + nonRobustInCircle + ", DD result = " + isInCircleDD + ", CC result = " + isInCircleCC + ")"); System.out.println(WKTWriter.toLineString(new CoordinateArraySequence( new Coordinate[] { a, b, c, p }))); System.out.println("Circumcentre = " + WKTWriter.toPoint(circumCentre) + " radius = " + a.distance(circumCentre)); System.out.println("p radius diff a = " + Math.abs(p.distance(circumCentre)/a.distance(circumCentre) - 1)); System.out.println("p radius diff b = " + Math.abs(p.distance(circumCentre)/b.distance(circumCentre) - 1)); System.out.println("p radius diff c = " + Math.abs(p.distance(circumCentre)/c.distance(circumCentre) - 1)); System.out.println(); } }
public Projectable2D incenter() { Triangle t = jtsTri(); Coordinate c = t.inCentre(); return new Point2D((float)c.x, (float)c.y); }
public float inradius() { Triangle t = jtsTri(); return 2 * (float)t.area() / perimeter(); }
private Triangle jtsTri() { return new Triangle( new Coordinate((double)a.x(), (double)a.y()), new Coordinate((double)b.x(), (double)b.y()), new Coordinate((double)c.x(), (double)c.y())); }
/** * Tests whether a triangular ring would be eroded completely by the given * buffer distance. * This is a precise test. It uses the fact that the inner buffer of a * triangle converges on the inCentre of the triangle (the point * equidistant from all sides). If the buffer distance is greater than the * distance of the inCentre from a side, the triangle will be eroded completely. * <p> * This test is important, since it removes a problematic case where * the buffer distance is slightly larger than the inCentre distance. * In this case the triangle buffer curve "inverts" with incorrect topology, * producing an incorrect hole in the buffer. * * @param triangleCoord * @param bufferDistance * @return */ private boolean isTriangleErodedCompletely( Coordinate[] triangleCoord, double bufferDistance) { Triangle tri = new Triangle(triangleCoord[0], triangleCoord[1], triangleCoord[2]); Coordinate inCentre = tri.inCentre(); double distToCentre = CGAlgorithms.distancePointLine(inCentre, tri.p0, tri.p1); return distToCentre < Math.abs(bufferDistance); }
/** * Computes the inCircle test using distance from the circumcentre. * Uses standard double-precision arithmetic. * <p> * In general this doesn't * appear to be any more robust than the standard calculation. However, there * is at least one case where the test point is far enough from the * circumcircle that this test gives the correct answer. * <pre> * LINESTRING * (1507029.9878 518325.7547, 1507022.1120341457 518332.8225183258, * 1507029.9833 518325.7458, 1507029.9896965567 518325.744909031) * </pre> * * @param a a vertex of the triangle * @param b a vertex of the triangle * @param c a vertex of the triangle * @param p the point to test * @return true if this point is inside the circle defined by the points a, b, c */ public static boolean isInCircleCC(Coordinate a, Coordinate b, Coordinate c, Coordinate p) { Coordinate cc = Triangle.circumcentre(a, b, c); double ccRadius = a.distance(cc); double pRadiusDiff = p.distance(cc) - ccRadius; return pRadiusDiff <= 0; }
/** * Computes the inCircle test using distance from the circumcentre. * Uses standard double-precision arithmetic. * <p/> * In general this doesn't * appear to be any more robust than the standard calculation. However, there * is at least one case where the test point is far enough from the * circumcircle that this test gives the correct answer. * <pre> * LINESTRING * (1507029.9878 518325.7547, 1507022.1120341457 518332.8225183258, * 1507029.9833 518325.7458, 1507029.9896965567 518325.744909031) * </pre> * * @param a a vertex of the triangle * @param b a vertex of the triangle * @param c a vertex of the triangle * @param p the point to test * @return true if this point is inside the circle defined by the points a, b, c */ public static boolean isInCircleCC(Coordinate a, Coordinate b, Coordinate c, Coordinate p) { Coordinate cc = Triangle.circumcentre(a, b, c); double ccRadius = a.distance(cc); double pRadiusDiff = p.distance(cc) - ccRadius; return pRadiusDiff <= 0; }