Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,46 @@ public static boolean isInCircleNormalized(
return disc > 0;
}

public static boolean isInCircleAdapt(
Coordinate a, Coordinate b, Coordinate c,
Coordinate p) {
double epsilon = Math.ulp(1.0);
double iccerrboundA = (10.0 + 96.0 * epsilon) * epsilon;
double adx = a.x - p.x;
double ady = a.y - p.y;
double bdx = b.x - p.x;
double bdy = b.y - p.y;
double cdx = c.x - p.x;
double cdy = c.y - p.y;

double bdxcdy = bdx * cdy;
double cdxbdy = cdx * bdy;
double alift = adx * adx + ady * ady;

double cdxady = cdx * ady;
double adxcdy = adx * cdy;
double blift = bdx * bdx + bdy * bdy;

double adxbdy = adx * bdy;
double bdxady = bdx * ady;
double clift = cdx * cdx + cdy * cdy;

double det = alift * (bdxcdy - cdxbdy)
+ blift * (cdxady - adxcdy)
+ clift * (adxbdy - bdxady);

double permanent = (Math.abs(bdxcdy) + Math.abs(cdxbdy)) * alift
+ (Math.abs(cdxady) + Math.abs(adxcdy)) * blift
+ (Math.abs(adxbdy) + Math.abs(bdxady)) * clift;
double errbound = iccerrboundA * permanent;
if (det > errbound) {
return true;
}
if (-det > errbound) {
return false;
}
return isInCircleDDFast(a, b, c, p);
}
/**
* Computes twice the area of the oriented triangle (a, b, c), i.e., the area is positive if the
* triangle is oriented counterclockwise.
Expand Down Expand Up @@ -123,9 +163,7 @@ public static boolean isInCircleRobust(
Coordinate a, Coordinate b, Coordinate c,
Coordinate p)
{
//checkRobustInCircle(a, b, c, p);
// return isInCircleNonRobust(a, b, c, p);
return isInCircleNormalized(a, b, c, p);
return isInCircleAdapt(a, b, c, p);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public void testGrid()
public void testCircle()
{
String wkt = "POLYGON ((42 30, 41.96 29.61, 41.85 29.23, 41.66 28.89, 41.41 28.59, 41.11 28.34, 40.77 28.15, 40.39 28.04, 40 28, 39.61 28.04, 39.23 28.15, 38.89 28.34, 38.59 28.59, 38.34 28.89, 38.15 29.23, 38.04 29.61, 38 30, 38.04 30.39, 38.15 30.77, 38.34 31.11, 38.59 31.41, 38.89 31.66, 39.23 31.85, 39.61 31.96, 40 32, 40.39 31.96, 40.77 31.85, 41.11 31.66, 41.41 31.41, 41.66 31.11, 41.85 30.77, 41.96 30.39, 42 30))";
String expected = "MULTILINESTRING ((41.66 31.11, 41.85 30.77), (41.41 31.41, 41.66 31.11), (41.11 31.66, 41.41 31.41), (40.77 31.85, 41.11 31.66), (40.39 31.96, 40.77 31.85), (40 32, 40.39 31.96), (39.61 31.96, 40 32), (39.23 31.85, 39.61 31.96), (38.89 31.66, 39.23 31.85), (38.59 31.41, 38.89 31.66), (38.34 31.11, 38.59 31.41), (38.15 30.77, 38.34 31.11), (38.04 30.39, 38.15 30.77), (38 30, 38.04 30.39), (38 30, 38.04 29.61), (38.04 29.61, 38.15 29.23), (38.15 29.23, 38.34 28.89), (38.34 28.89, 38.59 28.59), (38.59 28.59, 38.89 28.34), (38.89 28.34, 39.23 28.15), (39.23 28.15, 39.61 28.04), (39.61 28.04, 40 28), (40 28, 40.39 28.04), (40.39 28.04, 40.77 28.15), (40.77 28.15, 41.11 28.34), (41.11 28.34, 41.41 28.59), (41.41 28.59, 41.66 28.89), (41.66 28.89, 41.85 29.23), (41.85 29.23, 41.96 29.61), (41.96 29.61, 42 30), (41.96 30.39, 42 30), (41.85 30.77, 41.96 30.39), (41.66 31.11, 41.96 30.39), (41.41 31.41, 41.96 30.39), (41.41 28.59, 41.96 30.39), (41.41 28.59, 41.41 31.41), (38.59 28.59, 41.41 28.59), (38.59 28.59, 41.41 31.41), (38.59 28.59, 38.59 31.41), (38.59 31.41, 41.41 31.41), (38.59 31.41, 39.61 31.96), (39.61 31.96, 41.41 31.41), (39.61 31.96, 40.39 31.96), (40.39 31.96, 41.41 31.41), (40.39 31.96, 41.11 31.66), (38.04 30.39, 38.59 28.59), (38.04 30.39, 38.59 31.41), (38.04 30.39, 38.34 31.11), (38.04 29.61, 38.59 28.59), (38.04 29.61, 38.04 30.39), (39.61 28.04, 41.41 28.59), (38.59 28.59, 39.61 28.04), (38.89 28.34, 39.61 28.04), (40.39 28.04, 41.41 28.59), (39.61 28.04, 40.39 28.04), (41.96 29.61, 41.96 30.39), (41.41 28.59, 41.96 29.61), (41.66 28.89, 41.96 29.61), (40.39 28.04, 41.11 28.34), (38.04 29.61, 38.34 28.89), (38.89 31.66, 39.61 31.96))";
String expected = "MULTILINESTRING ((38 30, 38.04 29.61), (38 30, 38.04 30.39), (38.04 29.61, 38.04 30.39), (38.04 29.61, 38.15 29.23), (38.04 29.61, 38.34 28.89), (38.04 29.61, 38.59 28.59), (38.04 29.61, 38.59 31.41), (38.04 30.39, 38.15 30.77), (38.04 30.39, 38.34 31.11), (38.04 30.39, 38.59 31.41), (38.15 29.23, 38.34 28.89), (38.15 30.77, 38.34 31.11), (38.34 28.89, 38.59 28.59), (38.34 31.11, 38.59 31.41), (38.59 28.59, 38.59 31.41), (38.59 28.59, 38.89 28.34), (38.59 28.59, 39.61 28.04), (38.59 28.59, 40.39 28.04), (38.59 28.59, 41.41 28.59), (38.59 31.41, 38.89 31.66), (38.59 31.41, 39.61 31.96), (38.59 31.41, 40.39 31.96), (38.59 31.41, 41.41 28.59), (38.59 31.41, 41.41 31.41), (38.89 28.34, 39.23 28.15), (38.89 28.34, 39.61 28.04), (38.89 31.66, 39.23 31.85), (38.89 31.66, 39.61 31.96), (39.23 28.15, 39.61 28.04), (39.23 31.85, 39.61 31.96), (39.61 28.04, 40 28), (39.61 28.04, 40.39 28.04), (39.61 31.96, 40 32), (39.61 31.96, 40.39 31.96), (40 28, 40.39 28.04), (40 32, 40.39 31.96), (40.39 28.04, 40.77 28.15), (40.39 28.04, 41.11 28.34), (40.39 28.04, 41.41 28.59), (40.39 31.96, 40.77 31.85), (40.39 31.96, 41.11 31.66), (40.39 31.96, 41.41 31.41), (40.77 28.15, 41.11 28.34), (40.77 31.85, 41.11 31.66), (41.11 28.34, 41.41 28.59), (41.11 31.66, 41.41 31.41), (41.41 28.59, 41.41 31.41), (41.41 28.59, 41.66 28.89), (41.41 28.59, 41.96 29.61), (41.41 31.41, 41.66 31.11), (41.41 31.41, 41.96 29.61), (41.41 31.41, 41.96 30.39), (41.66 28.89, 41.85 29.23), (41.66 28.89, 41.96 29.61), (41.66 31.11, 41.85 30.77), (41.66 31.11, 41.96 30.39), (41.85 29.23, 41.96 29.61), (41.85 30.77, 41.96 30.39), (41.96 29.61, 41.96 30.39), (41.96 29.61, 42 30), (41.96 30.39, 42 30))";
checkDelaunayEdges(wkt, expected);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* Copyright (c) 2026 Darafei Praliaskouski.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v. 1.0 which accompanies this distribution.
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
*
* http://www.eclipse.org/org/documents/edl-v10.php.
*/

package org.locationtech.jts.triangulate.quadedge;

import junit.framework.TestCase;
import junit.textui.TestRunner;
import org.locationtech.jts.geom.Coordinate;

/**
* Tests for triangle predicates.
*/
public class TrianglePredicateTest extends TestCase {

public static void main(String args[]) {
TestRunner.run(TrianglePredicateTest.class);
}

public TrianglePredicateTest(String name) {
super(name);
}

public void testAdaptiveInCircleClearCases() {
Coordinate a = new Coordinate(0, 0);
Coordinate b = new Coordinate(10, 0);
Coordinate c = new Coordinate(0, 10);

assertTrue(TrianglePredicate.isInCircleRobust(a, b, c, new Coordinate(1, 1)));
assertFalse(TrianglePredicate.isInCircleRobust(a, b, c, new Coordinate(20, 20)));
}

public void testAdaptiveInCircleFallbackUsesDDComputation() {
Coordinate a = new Coordinate(100000000000000.19, 100000000000000.53);
Coordinate b = new Coordinate(100000000000000.19, 100000000000000.47);
Coordinate c = new Coordinate(100000000000000.22, 100000000000000.38);
Coordinate p = new Coordinate(100000000000000.40, 100000000000000.75);

assertTrue(TrianglePredicate.isInCircleDDFast(a, b, c, p));
assertTrue(TrianglePredicate.isInCircleRobust(a, b, c, p));
}
}