You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by kw...@apache.org on 2018/04/26 11:14:57 UTC

lucene-solr:master: LUCENE-8276: Add new tests which demonstrate the issue. Only one is now failing.

Repository: lucene-solr
Updated Branches:
  refs/heads/master e331c068d -> 8e029816c


LUCENE-8276: Add new tests which demonstrate the issue.  Only one is now failing.


Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/8e029816
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/8e029816
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/8e029816

Branch: refs/heads/master
Commit: 8e029816cf82b4523c047e04818d16dc940aa72f
Parents: e331c06
Author: Karl Wright <Da...@gmail.com>
Authored: Thu Apr 26 07:14:27 2018 -0400
Committer: Karl Wright <Da...@gmail.com>
Committed: Thu Apr 26 07:14:27 2018 -0400

----------------------------------------------------------------------
 .../lucene/spatial3d/geom/GeoPolygonTest.java   |  55 +++++
 .../spatial3d/geom/RandomGeoPolygonTest.java    | 247 +++++++++++--------
 2 files changed, 195 insertions(+), 107 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/8e029816/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoPolygonTest.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoPolygonTest.java b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoPolygonTest.java
index 3eafb5a..0c903b6 100755
--- a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoPolygonTest.java
+++ b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoPolygonTest.java
@@ -1684,6 +1684,61 @@ shape:
     assertFalse(largePolygon.isWithin(point));
   }
 
+  @Test
+  public void testLUCENE8276_case1() {
+    //POLYGON((1.0517792672527197E-4 -1.592702733911458E-5,1.0324192726355287E-4 2.5741558803919037E-5,7.879018764391666E-5 7.192932029677136E-5,0.0 9.400459451570553E-24,3.50020551583809E-5 -6.508699856255637E-5,1.0517792672527197E-4 -1.592702733911458E-5))
+    final List<GeoPoint> points = new ArrayList<>();
+    points.add(new GeoPoint(PlanetModel.SPHERE, Geo3DUtil.fromDegrees(-1.592702733911458E-5), Geo3DUtil.fromDegrees(1.0517792672527197E-4)));
+    points.add(new GeoPoint(PlanetModel.SPHERE, Geo3DUtil.fromDegrees(2.5741558803919037E-5), Geo3DUtil.fromDegrees(1.0324192726355287E-4)));
+    points.add(new GeoPoint(PlanetModel.SPHERE, Geo3DUtil.fromDegrees(7.192932029677136E-5), Geo3DUtil.fromDegrees(7.879018764391666E-5)));
+    points.add(new GeoPoint(PlanetModel.SPHERE, Geo3DUtil.fromDegrees(9.400459451570553E-24), Geo3DUtil.fromDegrees(0.0)));
+    points.add(new GeoPoint(PlanetModel.SPHERE, Geo3DUtil.fromDegrees(-6.508699856255637E-5), Geo3DUtil.fromDegrees(3.50020551583809E-5)));
+    final GeoPolygonFactory.PolygonDescription description = new GeoPolygonFactory.PolygonDescription(points);
+    final GeoPolygon polygon = GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, description);
+    final GeoPolygon largePolygon = GeoPolygonFactory.makeLargeGeoPolygon(PlanetModel.SPHERE, Collections.singletonList(description));
+
+    //POINT(-1.13E-321 2.83E-321)
+    final GeoPoint point = new GeoPoint(PlanetModel.SPHERE, Geo3DUtil.fromDegrees(-1.13E-321), Geo3DUtil.fromDegrees(-1.13E-321));
+    assertTrue(polygon.isWithin(point) == largePolygon.isWithin(point));
+  }
+
+  @Test
+  public void testLUCENE8276_case2() {
+    //POLYGON((0.05925400271049228 -0.08922986460239596,0.07309863706879852 -0.07813330646578831,0.07411491387725304 -0.07715685640120272,0.0 -2.8E-322,-0.005013788374470427 0.06774540608427036,-0.09349862417147398 0.051577774969906794,-0.10359306491815146 -0.02537375818592368,0.05925400271049228 -0.08922986460239596))
+    final List<GeoPoint> points = new ArrayList<>();
+    points.add(new GeoPoint(PlanetModel.SPHERE, Geo3DUtil.fromDegrees(-0.08922986460239596), Geo3DUtil.fromDegrees(0.05925400271049228)));
+    points.add(new GeoPoint(PlanetModel.SPHERE, Geo3DUtil.fromDegrees(-0.07813330646578831), Geo3DUtil.fromDegrees(0.07309863706879852)));
+    points.add(new GeoPoint(PlanetModel.SPHERE, Geo3DUtil.fromDegrees(-0.07715685640120272), Geo3DUtil.fromDegrees(0.07411491387725304)));
+    points.add(new GeoPoint(PlanetModel.SPHERE, Geo3DUtil.fromDegrees(-2.8E-322), Geo3DUtil.fromDegrees(0.0)));
+    points.add(new GeoPoint(PlanetModel.SPHERE, Geo3DUtil.fromDegrees(0.06774540608427036), Geo3DUtil.fromDegrees(-0.005013788374470427)));
+    points.add(new GeoPoint(PlanetModel.SPHERE, Geo3DUtil.fromDegrees(0.051577774969906794), Geo3DUtil.fromDegrees(-0.09349862417147398)));
+    points.add(new GeoPoint(PlanetModel.SPHERE, Geo3DUtil.fromDegrees(-0.02537375818592368), Geo3DUtil.fromDegrees(-0.10359306491815146)));
+    final GeoPolygonFactory.PolygonDescription description = new GeoPolygonFactory.PolygonDescription(points);
+    final GeoPolygon polygon = GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, description);
+    final GeoPolygon largePolygon = GeoPolygonFactory.makeLargeGeoPolygon(PlanetModel.SPHERE, Collections.singletonList(description));
+
+    //POINT(9.020991048228685E-4 -2.5357127427108625E-98)
+    final GeoPoint point = new GeoPoint(PlanetModel.SPHERE, Geo3DUtil.fromDegrees(-2.5357127427108625E-98), Geo3DUtil.fromDegrees(9.020991048228685E-4));
+    assertTrue(polygon.isWithin(point) == largePolygon.isWithin(point));
+  }
 
+  @Test
+  @AwaitsFix(bugUrl="https://issues.apache.org/jira/browse/LUCENE-8276")
+  public void testLUCENE8276_case3() {
+    //POLYGON((2.693381024483753E-4 -0.001073608118084019,1.5848404608659423E-4 -2.6378130512803985E-4,8.981079660799132E-4 -6.4697719116416E-4,-7.934854852157693E-5 4.193687767358618E-4,0.0 8.013660459916381E-131,-3.968797970346633E-4 3.2057826073172334E-4,2.693381024483753E-4 -0.001073608118084019))
+    final List<GeoPoint> points = new ArrayList<>();
+    points.add(new GeoPoint(PlanetModel.SPHERE, Geo3DUtil.fromDegrees(-0.001073608118084019), Geo3DUtil.fromDegrees(2.693381024483753E-4)));
+    points.add(new GeoPoint(PlanetModel.SPHERE, Geo3DUtil.fromDegrees(-2.6378130512803985E-4), Geo3DUtil.fromDegrees(1.5848404608659423E-4)));
+    points.add(new GeoPoint(PlanetModel.SPHERE, Geo3DUtil.fromDegrees(-6.4697719116416E-4), Geo3DUtil.fromDegrees(8.981079660799132E-4)));
+    points.add(new GeoPoint(PlanetModel.SPHERE, Geo3DUtil.fromDegrees(4.193687767358618E-4), Geo3DUtil.fromDegrees(-7.934854852157693E-5)));
+    points.add(new GeoPoint(PlanetModel.SPHERE, Geo3DUtil.fromDegrees(8.013660459916381E-131), Geo3DUtil.fromDegrees(0.0)));
+    points.add(new GeoPoint(PlanetModel.SPHERE, Geo3DUtil.fromDegrees(3.2057826073172334E-4), Geo3DUtil.fromDegrees(-3.968797970346633E-4)));
+    final GeoPolygonFactory.PolygonDescription description = new GeoPolygonFactory.PolygonDescription(points);
+    final GeoPolygon polygon = GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, description);
+    final GeoPolygon largePolygon = GeoPolygonFactory.makeLargeGeoPolygon(PlanetModel.SPHERE, Collections.singletonList(description));
 
+    //POINT(-2.394808631784144E-4 5.7E-322)
+    final GeoPoint point = new GeoPoint(PlanetModel.SPHERE, Geo3DUtil.fromDegrees(5.7E-322), Geo3DUtil.fromDegrees(-2.394808631784144E-4));
+    assertTrue(polygon.isWithin(point) == largePolygon.isWithin(point));
+  }
 }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/8e029816/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/RandomGeoPolygonTest.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/RandomGeoPolygonTest.java b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/RandomGeoPolygonTest.java
index a181d17..25b518c 100644
--- a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/RandomGeoPolygonTest.java
+++ b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/RandomGeoPolygonTest.java
@@ -77,120 +77,152 @@ public class RandomGeoPolygonTest extends RandomGeo3dShapeGenerator {
   public void testCoplanarityTilePolygon() {
     //POLYGON((-90.55764 -0.34907,-90.55751 -0.34868,-90.55777 -0.34842,-90.55815 -0.34766,-90.55943 -0.34842, -90.55918 -0.34842,-90.55764 -0.34907))
     List<GeoPoint> points = new ArrayList<>();
-    points.add(new GeoPoint(PlanetModel.SPHERE, fromDegrees(-0.34907), fromDegrees(-90.55764)));
-    points.add(new GeoPoint(PlanetModel.SPHERE, fromDegrees(-0.34868), fromDegrees(-90.55751)));
-    points.add(new GeoPoint(PlanetModel.SPHERE, fromDegrees(-0.34842), fromDegrees(-90.55777)));
-    points.add(new GeoPoint(PlanetModel.SPHERE, fromDegrees(-0.34766), fromDegrees(-90.55815)));
-    points.add(new GeoPoint(PlanetModel.SPHERE, fromDegrees(-0.34842), fromDegrees(-90.55943)));
-    points.add(new GeoPoint(PlanetModel.SPHERE, fromDegrees(-0.34842), fromDegrees(-90.55918)));
+    points.add(new GeoPoint(PlanetModel.SPHERE, Geo3DUtil.fromDegrees(-0.34907), Geo3DUtil.fromDegrees(-90.55764)));
+    points.add(new GeoPoint(PlanetModel.SPHERE, Geo3DUtil.fromDegrees(-0.34868), Geo3DUtil.fromDegrees(-90.55751)));
+    points.add(new GeoPoint(PlanetModel.SPHERE, Geo3DUtil.fromDegrees(-0.34842), Geo3DUtil.fromDegrees(-90.55777)));
+    points.add(new GeoPoint(PlanetModel.SPHERE, Geo3DUtil.fromDegrees(-0.34766), Geo3DUtil.fromDegrees(-90.55815)));
+    points.add(new GeoPoint(PlanetModel.SPHERE, Geo3DUtil.fromDegrees(-0.34842), Geo3DUtil.fromDegrees(-90.55943)));
+    points.add(new GeoPoint(PlanetModel.SPHERE, Geo3DUtil.fromDegrees(-0.34842), Geo3DUtil.fromDegrees(-90.55918)));
     GeoCompositePolygon polygon = (GeoCompositePolygon)GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, points);
     assertTrue(polygon.size() == 3);
   }
 
   /**
-   * Test comparing different polygon technologies using random
+   * Test comparing different polygon (Big) technologies using random
    * biased doubles.
    */
   @Test
   @Repeat(iterations = 10)
-  public void testComparePolygons() {
+  public void testCompareBigPolygons() {
+    testComparePolygons(Math.PI);
+  }
+
+  /**
+   * Test comparing different polygon (Small) technologies using random
+   * biased doubles.
+   */
+  @Test
+  @Repeat(iterations = 10)
+  public void testCompareSmallPolygons() {
+    testComparePolygons(1e-4 * Math.PI);
+  }
+
+
+  private void testComparePolygons(double limitDistance) {
     final PlanetModel planetModel = randomPlanetModel();
     //Create polygon points using a reference point and a maximum distance to the point
-    final GeoPoint referencePoint = getBiasedPoint(planetModel);
+    final GeoPoint referencePoint;
+    if (random().nextBoolean()) {
+     referencePoint = getBiasedPoint(planetModel);
+    } else {
+      referencePoint = randomGeoPoint(planetModel);
+    }
     final int n = random().nextInt(4) + 4;
     final List<GeoPoint> points = new ArrayList<>(n);
-    final double maxDistance = random().nextDouble() *  Math.PI;
-    for (int i = 0; i < n; i++) {
-      while(true) {
-        final double distance = BiasedNumbers.randomDoubleBetween(random(), 0, maxDistance);// random().nextDouble() * maxDistance;
-        final double bearing = random().nextDouble() * 2 * Math.PI;
-        GeoPoint p = planetModel.surfacePointOnBearing(referencePoint, distance, bearing);
-        if (!contains(p, points)) {
-          if (points.size() > 1 && Plane.arePointsCoplanar(points.get(points.size() -1), points.get(points.size() - 2), p)) {
-            continue;
+    List<GeoPoint> orderedPoints = null;
+    GeoPolygon polygon = null;
+    GeoPolygon largePolygon = null;
+    do {
+      double maxDistance = random().nextDouble() * limitDistance;
+      //if distance is too small we can fail
+      //building the polygon.
+      while (maxDistance < 1e-7) {
+        maxDistance = random().nextDouble() * limitDistance;
+      }
+      for (int i = 0; i < n; i++) {
+        while (true) {
+          final double distance = BiasedNumbers.randomDoubleBetween(random(), 0, maxDistance);// random().nextDouble() * maxDistance;
+          final double bearing = random().nextDouble() * 2 * Math.PI;
+          final GeoPoint p = planetModel.surfacePointOnBearing(referencePoint, distance, bearing);
+          if (!contains(p, points)) {
+            if (points.size() > 1 && Plane.arePointsCoplanar(points.get(points.size() - 1), points.get(points.size() - 2), p)) {
+              continue;
+            }
+            points.add(p);
+            break;
           }
-          points.add(p);
-          break;
         }
       }
+      //order points so we don't get crossing edges
+      orderedPoints = orderPoints(points);
+      if (random().nextBoolean() && random().nextBoolean()) {
+        Collections.reverse(orderedPoints);
+      }
+      final GeoPolygonFactory.PolygonDescription polygonDescription = new GeoPolygonFactory.PolygonDescription(orderedPoints);
+
+      try {
+        polygon = GeoPolygonFactory.makeGeoPolygon(planetModel, polygonDescription);
+      } catch (Exception e) {
+        final StringBuilder buffer = new StringBuilder("Polygon failed to build with an exception:\n");
+        buffer.append(points.toString() + "\n");
+        buffer.append("WKT:" + getWKT(orderedPoints));
+        buffer.append(e.toString());
+        fail(buffer.toString());
+      }
+      if (polygon == null) {
+        final StringBuilder buffer = new StringBuilder("Polygon failed to build:\n");
+        buffer.append(points.toString() + "\n");
+        buffer.append("WKT:" + getWKT(orderedPoints));
+        fail(buffer.toString());
+      }
+      try {
+        largePolygon = GeoPolygonFactory.makeLargeGeoPolygon(planetModel, Collections.singletonList(polygonDescription));
+      } catch (Exception e) {
+        final StringBuilder buffer = new StringBuilder("Large polygon failed to build with an exception:\n");
+        buffer.append(points.toString() + "\n");
+        buffer.append("WKT:" + getWKT(orderedPoints));
+        buffer.append(e.toString());
+        fail(buffer.toString());
+      }
+      if (largePolygon == null) {
+        StringBuilder buffer = new StringBuilder("Large polygon failed to build:\n");
+        buffer.append(points.toString() + "\n");
+        buffer.append("WKT:" + getWKT(orderedPoints));
+        fail(buffer.toString());
+      }
+    } while(polygon.getClass().equals(largePolygon.getClass()));
+    //Some of these do not work but it seems it s from the way the point is created
+    //GeoPoint centerOfMass = getCenterOfMass(planetModel, orderedPoints);
+    //checkPoint(polygon, largePolygon, centerOfMass, orderedPoints);
+    //checkPoint(polygon, largePolygon, new GeoPoint(-centerOfMass.x, -centerOfMass.y, -centerOfMass.z), orderedPoints);
+    //checkPoint(polygon, largePolygon, new GeoPoint(centerOfMass.x, -centerOfMass.y, -centerOfMass.z), orderedPoints);
+    //checkPoint(polygon, largePolygon, new GeoPoint(centerOfMass.x, centerOfMass.y, -centerOfMass.z), orderedPoints);
+    //checkPoint(polygon, largePolygon, new GeoPoint(-centerOfMass.x, -centerOfMass.y, centerOfMass.z), orderedPoints);
+    //checkPoint(polygon, largePolygon, new GeoPoint(-centerOfMass.x, centerOfMass.y, -centerOfMass.z), orderedPoints);
+    //checkPoint(polygon, largePolygon, new GeoPoint(centerOfMass.x, -centerOfMass.y, centerOfMass.z), orderedPoints);
+    for(int i = 0; i < 100000; i++) {
+      final GeoPoint point;
+      if (random().nextBoolean()) {
+        point = getBiasedPoint(planetModel);
+      } else {
+        point = randomGeoPoint(planetModel);
+      }
+      checkPoint(polygon, largePolygon, point, orderedPoints);
     }
-    //order points so we don't get crossing edges
-    final List<GeoPoint> orderedPoints = orderPoints(points);
-    //Comment out below to get clock-wise polygons
-    if (random().nextBoolean() && random().nextBoolean()) {
-      Collections.reverse(orderedPoints);
-    }
-    GeoPolygonFactory.PolygonDescription polygonDescription = new GeoPolygonFactory.PolygonDescription(orderedPoints);
-    GeoPolygon polygon = null;
-    try {
-      polygon = GeoPolygonFactory.makeGeoPolygon(planetModel, polygonDescription);
-    } catch(Exception e) {
-      StringBuilder buffer = new StringBuilder("Polygon failed to build with an exception:\n");
-      buffer.append(points.toString()+ "\n");
-      buffer.append("WKT:" + getWKT(orderedPoints));
-      buffer.append(e.toString());
-      fail(buffer.toString());
-    }
-    if (polygon == null) {
-      StringBuilder buffer = new StringBuilder("Polygon failed to build:\n");
-      buffer.append(points.toString()+ "\n");
-      buffer.append("WKT:" + getWKT(orderedPoints));
-      fail(buffer.toString());
-    }
-    GeoPolygon largePolygon = null;
-    try {
-      largePolygon = GeoPolygonFactory.makeLargeGeoPolygon(planetModel, Collections.singletonList(polygonDescription));
-    } catch(Exception e) {
-      StringBuilder buffer = new StringBuilder("Large polygon failed to build with an exception:\n");
-      buffer.append(points.toString()+ "\n");
-      buffer.append("WKT:" + getWKT(orderedPoints));
-      buffer.append(e.toString());
-      fail(buffer.toString());
-    }
-    if (largePolygon == null) {
-      StringBuilder buffer = new StringBuilder("Large polygon failed to build:\n");
-      buffer.append(points.toString()+ "\n");
-      buffer.append("WKT:" + getWKT(orderedPoints));
-      fail(buffer.toString());
-    }
+  }
 
-    for(int i=0;i<100000;i++) {
-      GeoPoint point = getBiasedPoint(planetModel);
-      boolean withIn1 = polygon.isWithin(point);
-      boolean withIn2 = largePolygon.isWithin(point);
-      StringBuilder buffer = new StringBuilder();
-      if (withIn1 != withIn2) {
-        //NOTE: Sometimes we get errors when check point is near a polygon point.
-        // For the time being, we filter this errors.
-        double d1 = polygon.computeOutsideDistance(DistanceStyle.ARC, point);
-        double d2  = largePolygon.computeOutsideDistance(DistanceStyle.ARC, point);
-        if (d1 == 0 && d2 == 0) {
-          continue;
-        }
-        buffer = buffer.append("\nStandard polygon: " + polygon.toString() +"\n");
-        buffer = buffer.append("\nLarge polygon: " + largePolygon.toString() +"\n");
-        buffer = buffer.append("\nPoint: " + point.toString() +"\n");
-        buffer.append("\nWKT: " + getWKT(orderedPoints));
-        buffer.append("\nWKT: POINT(" + toDegrees(point.getLongitude()) + " " + toDegrees(point.getLatitude()) + ")\n");
-        buffer.append("normal polygon: " +withIn1 + "\n");
-        buffer.append("large polygon: " + withIn2 + "\n");
+  private void checkPoint(final GeoPolygon polygon, final GeoPolygon largePolygon, final GeoPoint point, final List<GeoPoint> orderedPoints) {
+    final boolean withIn1 = polygon.isWithin(point);
+    final boolean withIn2 = largePolygon.isWithin(point);
+    StringBuilder buffer = new StringBuilder();
+    if (withIn1 != withIn2) {
+      //NOTE: Standard and large polygon are mathematically slightly different
+      //close to the edges (due to bounding planes). Nothing we can do about that
+      //so we filter the differences.
+      final double d1 = polygon.computeOutsideDistance(DistanceStyle.ARC, point);
+      final double d2  = largePolygon.computeOutsideDistance(DistanceStyle.ARC, point);
+      if (d1 == 0 && d2 == 0) {
+        return;
       }
-      assertTrue(buffer.toString(), withIn1 == withIn2);
+      buffer = buffer.append("\nStandard polygon: " + polygon.toString() +"\n");
+      buffer = buffer.append("\nLarge polygon: " + largePolygon.toString() +"\n");
+      buffer = buffer.append("\nPoint: " + point.toString() +"\n");
+      buffer.append("\nWKT: " + getWKT(orderedPoints));
+      buffer.append("\nWKT: POINT(" + Geo3DUtil.toDegrees(point.getLongitude()) + " " + Geo3DUtil.toDegrees(point.getLatitude()) + ")\n");
+      buffer.append("normal polygon: " +withIn1 + "\n");
+      buffer.append("large polygon: " + withIn2 + "\n");
     }
-    //Not yet tested
-//    for(int i=0;i<100;i++) {
-//      GeoShape shape = randomGeoShape(randomShapeType(), planetModel);
-//      int rel1 = polygon.getRelationship(shape);
-//      int rel2 = largePolygon.getRelationship(shape);
-//      StringBuilder buffer = new StringBuilder();
-//      if (rel1 != rel2) {
-//        buffer = buffer.append(polygon.toString() +"\n" + shape.toString() + "\n");
-//        buffer.append("WKT: " + getWKT(orderedPoints) + "\n");
-//        buffer.append("normal polygon: " + rel1 + "\n");
-//        buffer.append("large polygon: " + rel2 + "\n");
-//      }
-//      assertTrue(buffer.toString(), rel1 == rel2);
-//    }
+    assertTrue(buffer.toString(), withIn1 == withIn2);
   }
 
   private GeoPoint getBiasedPoint(PlanetModel planetModel) {
@@ -208,9 +240,9 @@ public class RandomGeoPolygonTest extends RandomGeo3dShapeGenerator {
   private String getWKT(List<GeoPoint> points) {
     StringBuffer buffer = new StringBuffer("POLYGON((");
     for (GeoPoint point : points) {
-      buffer.append(toDegrees(point.getLongitude()) + " " + toDegrees(point.getLatitude()) + ",");
+      buffer.append(Geo3DUtil.toDegrees(point.getLongitude()) + " " + Geo3DUtil.toDegrees(point.getLatitude()) + ",");
     }
-    buffer.append(toDegrees(points.get(0).getLongitude()) + " " + toDegrees(points.get(0).getLatitude()) + "))\n");
+    buffer.append(Geo3DUtil.toDegrees(points.get(0).getLongitude()) + " " + Geo3DUtil.toDegrees(points.get(0).getLatitude()) + "))\n");
     return buffer.toString();
   }
 
@@ -222,18 +254,19 @@ public class RandomGeoPolygonTest extends RandomGeo3dShapeGenerator {
     }
     return false;
   }
-  
-  final private static double DEGREES_PER_RADIAN = 180.0 / Math.PI;
-  final private static double RADIANS_PER_DEGREE = Math.PI / 180.0;
-
-  /** Converts radians to degrees */
-  private static double toDegrees(final double radians) {
-    return radians * DEGREES_PER_RADIAN;
-  }
 
-  /** Converts radians to degrees */
-  private static double fromDegrees(final double degrees) {
-    return degrees * RADIANS_PER_DEGREE;
+  private GeoPoint getCenterOfMass(final PlanetModel planetModel, final List<GeoPoint> points) {
+    double x = 0;
+    double y = 0;
+    double z = 0;
+    //get center of mass
+    for (final GeoPoint point : points) {
+      x += point.x;
+      y += point.y;
+      z += point.z;
+    }
+    // Normalization is not needed because createSurfacePoint does the scaling anyway.
+    return planetModel.createSurfacePoint(x, y, z);
   }
 
 }


Re: lucene-solr:master: LUCENE-8276: Add new tests which demonstrate the issue. Only one is now failing.

Posted by Adrien Grand <jp...@gmail.com>.
Karl, this commit seems to be introducing new failures such as the
following:

*13:03:49*    [junit4] Suite:
org.apache.lucene.spatial3d.geom.RandomGeoPolygonTest*13:03:49*
[junit4]   2> NOTE: reproduce with: ant test
-Dtestcase=RandomGeoPolygonTest
-Dtests.method=testCompareSmallPolygons -Dtests.seed=5A8225EF62C5FD14
-Dtests.slow=true -Dtests.badapples=true -Dtests.locale=ro-RO
-Dtests.timezone=Australia/Broken_Hill -Dtests.asserts=true
-Dtests.file.encoding=UTF8*13:03:49*    [junit4] FAILURE 0.05s J1 |
RandomGeoPolygonTest.testCompareSmallPolygons
{seed=[5A8225EF62C5FD14:EE055490131C897F]} <<<*13:03:49*    [junit4]
 > Throwable #1: java.lang.AssertionError: *13:03:49*    [junit4]    >
Standard polygon: GeoCompositePolygon: {[GeoConvexPolygon:
{planetmodel=PlanetModel.SPHERE, points=[[lat=-3.4997017751302744E-6,
lon=-1.9104957367233055E-6([X=0.9999999999920512,
Y=-1.9104957367104438E-6, Z=-3.4997017751231314E-6])],
[lat=-7.240371388770696E-6,
lon=-1.1605326690755646E-6([X=0.9999999999731153,
Y=-1.160532669044885E-6, Z=-7.240371388707437E-6])],
[lat=2.419122758401074E-204, lon=0.0([X=1.0, Y=0.0,
Z=2.419122758401074E-204])], [lat=1.2509574330309563E-8,
lon=-1.624561463131613E-8([X=1.0, Y=-1.624561463131613E-8,
Z=1.2509574330309566E-8])]], internalEdges={3}}, GeoConvexPolygon:
{planetmodel=PlanetModel.SPHERE, points=[[lat=3.8278074582174365E-6,
lon=-6.939157373153648E-7([X=0.9999999999924334,
Y=-6.939157373102256E-7, Z=3.8278074582080895E-6])],
[lat=1.119200289477475E-6,
lon=-1.3888437067066661E-6([X=0.9999999999984093,
Y=-1.3888437067053498E-6, Z=1.1192002894772413E-6])],
[lat=-3.4997017751302744E-6,
lon=-1.9104957367233055E-6([X=0.9999999999920512,
Y=-1.9104957367104438E-6, Z=-3.4997017751231314E-6])],
[lat=1.2509574330309563E-8, lon=-1.624561463131613E-8([X=1.0,
Y=-1.624561463131613E-8, Z=1.2509574330309566E-8])]],
internalEdges={2, 3}}, GeoConvexPolygon:
{planetmodel=PlanetModel.SPHERE, points=[[lat=3.8278074582174365E-6,
lon=-6.939157373153648E-7([X=0.9999999999924334,
Y=-6.939157373102256E-7, Z=3.8278074582080895E-6])],
[lat=1.2509574330309563E-8, lon=-1.624561463131613E-8([X=1.0,
Y=-1.624561463131613E-8, Z=1.2509574330309566E-8])],
[lat=1.6742818931699996E-6,
lon=8.875002706076884E-7([X=0.9999999999982045, Y=8.87500270606328E-7,
Z=1.6742818931692173E-6])]], internalEdges={0}}]}*13:03:49*
[junit4]    > Large polygon: GeoComplexPolygon:
{planetmodel=PlanetModel.SPHERE, number of shapes=1, address=bf46e323,
testPoint=[lat=-5.866105640959045E-7,
lon=-6.117904562604815E-7([X=0.9999999999996407,
Y=-6.11790456260338E-7, Z=-5.866105640958707E-7])],
testPointInSet=true, shapes={ {[lat=-7.240371388770696E-6,
lon=-1.1605326690755646E-6([X=0.9999999999731153,
Y=-1.160532669044885E-6, Z=-7.240371388707437E-6])],
[lat=2.419122758401074E-204, lon=0.0([X=1.0, Y=0.0,
Z=2.419122758401074E-204])], [lat=1.2509574330309563E-8,
lon=-1.624561463131613E-8([X=1.0, Y=-1.624561463131613E-8,
Z=1.2509574330309566E-8])], [lat=1.6742818931699996E-6,
lon=8.875002706076884E-7([X=0.9999999999982045, Y=8.87500270606328E-7,
Z=1.6742818931692173E-6])], [lat=3.8278074582174365E-6,
lon=-6.939157373153648E-7([X=0.9999999999924334,
Y=-6.939157373102256E-7, Z=3.8278074582080895E-6])],
[lat=1.119200289477475E-6,
lon=-1.3888437067066661E-6([X=0.9999999999984093,
Y=-1.3888437067053498E-6, Z=1.1192002894772413E-6])],
[lat=-3.4997017751302744E-6,
lon=-1.9104957367233055E-6([X=0.9999999999920512,
Y=-1.9104957367104438E-6, Z=-3.4997017751231314E-6])]}}*13:03:49*
[junit4]    > Point: [lat=3.2042050955302614E-6,
lon=-0.0([X=0.9999999999948666, Y=-0.0,
Z=3.2042050955247785E-6])]*13:03:49*    [junit4]    > WKT:
POLYGON((0.0 1.3860552418042745E-202,-9.308051539703931E-7
7.167458126319312E-7,5.085001982253901E-5
9.592928619381434E-5,-3.975844308587909E-5
2.193172121445583E-4,-7.957488279759712E-5
6.412545301687931E-5,-1.0946334249198229E-4
-2.0051814126940701E-4,-6.649362392508249E-5 -4.148427226838355E-4,0.0
1.3860552418042745E-202))*13:03:49*    [junit4]    > WKT: POINT(-0.0
1.8358742866819673E-4)*13:03:49*    [junit4]    > normal polygon:
false*13:03:49*    [junit4]    > large polygon: true*13:03:49*
[junit4]    > 	at
__randomizedtesting.SeedInfo.seed([5A8225EF62C5FD14:EE055490131C897F]:0)*13:03:49*
   [junit4]    > 	at
org.apache.lucene.spatial3d.geom.RandomGeoPolygonTest.checkPoint(RandomGeoPolygonTest.java:225)*13:03:49*
   [junit4]    > 	at
org.apache.lucene.spatial3d.geom.RandomGeoPolygonTest.testComparePolygons(RandomGeoPolygonTest.java:200)*13:03:49*
   [junit4]    > 	at
org.apache.lucene.spatial3d.geom.RandomGeoPolygonTest.testCompareSmallPolygons(RandomGeoPolygonTest.java:107)*13:03:49*
   [junit4]    > 	at java.lang.Thread.run(Thread.java:748)*13:03:49*
 [junit4]   2> NOTE: test params are: codec=Asserting(Lucene70): {},
docValues:{}, maxPointsInLeafNode=1950,
maxMBSortInHeap=7.442893192380558,
sim=Asserting(org.apache.lucene.search.similarities.AssertingSimilarity@3381e2f8),
locale=ro-RO, timezone=Australia/Broken_Hill*13:03:49*    [junit4]
2> NOTE: Linux 3.10.0-693.5.2.el7.x86_64 amd64/Oracle Corporation
1.8.0_161 (64-bit)/cpus=4,threads=1,free=185859184,total=241696768*13:03:49*
   [junit4]   2> NOTE: All tests run in this JVM: [TestGeo3DPoint,
RandomGeoPolygonTest]*13:03:49*    [junit4] Completed [18/18 (1!)] on
J1 in 5.10s, 32 tests, 1 failure <<< FAILURES!


Le jeu. 26 avr. 2018 à 13:14, <kw...@apache.org> a écrit :

> Repository: lucene-solr
> Updated Branches:
>   refs/heads/master e331c068d -> 8e029816c
>
>
> LUCENE-8276: Add new tests which demonstrate the issue.  Only one is now
> failing.
>
>
> Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
> Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/8e029816
> Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/8e029816
> Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/8e029816
>
> Branch: refs/heads/master
> Commit: 8e029816cf82b4523c047e04818d16dc940aa72f
> Parents: e331c06
> Author: Karl Wright <Da...@gmail.com>
> Authored: Thu Apr 26 07:14:27 2018 -0400
> Committer: Karl Wright <Da...@gmail.com>
> Committed: Thu Apr 26 07:14:27 2018 -0400
>
> ----------------------------------------------------------------------
>  .../lucene/spatial3d/geom/GeoPolygonTest.java   |  55 +++++
>  .../spatial3d/geom/RandomGeoPolygonTest.java    | 247 +++++++++++--------
>  2 files changed, 195 insertions(+), 107 deletions(-)
> ----------------------------------------------------------------------
>
>
>
> http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/8e029816/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoPolygonTest.java
> ----------------------------------------------------------------------
> diff --git
> a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoPolygonTest.java
> b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoPolygonTest.java
> index 3eafb5a..0c903b6 100755
> ---
> a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoPolygonTest.java
> +++
> b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/GeoPolygonTest.java
> @@ -1684,6 +1684,61 @@ shape:
>      assertFalse(largePolygon.isWithin(point));
>    }
>
> +  @Test
> +  public void testLUCENE8276_case1() {
> +    //POLYGON((1.0517792672527197E-4
> -1.592702733911458E-5,1.0324192726355287E-4
> 2.5741558803919037E-5,7.879018764391666E-5 7.192932029677136E-5,0.0
> 9.400459451570553E-24,3.50020551583809E-5
> -6.508699856255637E-5,1.0517792672527197E-4 -1.592702733911458E-5))
> +    final List<GeoPoint> points = new ArrayList<>();
> +    points.add(new GeoPoint(PlanetModel.SPHERE,
> Geo3DUtil.fromDegrees(-1.592702733911458E-5),
> Geo3DUtil.fromDegrees(1.0517792672527197E-4)));
> +    points.add(new GeoPoint(PlanetModel.SPHERE,
> Geo3DUtil.fromDegrees(2.5741558803919037E-5),
> Geo3DUtil.fromDegrees(1.0324192726355287E-4)));
> +    points.add(new GeoPoint(PlanetModel.SPHERE,
> Geo3DUtil.fromDegrees(7.192932029677136E-5),
> Geo3DUtil.fromDegrees(7.879018764391666E-5)));
> +    points.add(new GeoPoint(PlanetModel.SPHERE,
> Geo3DUtil.fromDegrees(9.400459451570553E-24), Geo3DUtil.fromDegrees(0.0)));
> +    points.add(new GeoPoint(PlanetModel.SPHERE,
> Geo3DUtil.fromDegrees(-6.508699856255637E-5),
> Geo3DUtil.fromDegrees(3.50020551583809E-5)));
> +    final GeoPolygonFactory.PolygonDescription description = new
> GeoPolygonFactory.PolygonDescription(points);
> +    final GeoPolygon polygon =
> GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, description);
> +    final GeoPolygon largePolygon =
> GeoPolygonFactory.makeLargeGeoPolygon(PlanetModel.SPHERE,
> Collections.singletonList(description));
> +
> +    //POINT(-1.13E-321 2.83E-321)
> +    final GeoPoint point = new GeoPoint(PlanetModel.SPHERE,
> Geo3DUtil.fromDegrees(-1.13E-321), Geo3DUtil.fromDegrees(-1.13E-321));
> +    assertTrue(polygon.isWithin(point) == largePolygon.isWithin(point));
> +  }
> +
> +  @Test
> +  public void testLUCENE8276_case2() {
> +    //POLYGON((0.05925400271049228
> -0.08922986460239596,0.07309863706879852
> -0.07813330646578831,0.07411491387725304 -0.07715685640120272,0.0
> -2.8E-322,-0.005013788374470427 0.06774540608427036,-0.09349862417147398
> 0.051577774969906794,-0.10359306491815146
> -0.02537375818592368,0.05925400271049228 -0.08922986460239596))
> +    final List<GeoPoint> points = new ArrayList<>();
> +    points.add(new GeoPoint(PlanetModel.SPHERE,
> Geo3DUtil.fromDegrees(-0.08922986460239596),
> Geo3DUtil.fromDegrees(0.05925400271049228)));
> +    points.add(new GeoPoint(PlanetModel.SPHERE,
> Geo3DUtil.fromDegrees(-0.07813330646578831),
> Geo3DUtil.fromDegrees(0.07309863706879852)));
> +    points.add(new GeoPoint(PlanetModel.SPHERE,
> Geo3DUtil.fromDegrees(-0.07715685640120272),
> Geo3DUtil.fromDegrees(0.07411491387725304)));
> +    points.add(new GeoPoint(PlanetModel.SPHERE,
> Geo3DUtil.fromDegrees(-2.8E-322), Geo3DUtil.fromDegrees(0.0)));
> +    points.add(new GeoPoint(PlanetModel.SPHERE,
> Geo3DUtil.fromDegrees(0.06774540608427036),
> Geo3DUtil.fromDegrees(-0.005013788374470427)));
> +    points.add(new GeoPoint(PlanetModel.SPHERE,
> Geo3DUtil.fromDegrees(0.051577774969906794),
> Geo3DUtil.fromDegrees(-0.09349862417147398)));
> +    points.add(new GeoPoint(PlanetModel.SPHERE,
> Geo3DUtil.fromDegrees(-0.02537375818592368),
> Geo3DUtil.fromDegrees(-0.10359306491815146)));
> +    final GeoPolygonFactory.PolygonDescription description = new
> GeoPolygonFactory.PolygonDescription(points);
> +    final GeoPolygon polygon =
> GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, description);
> +    final GeoPolygon largePolygon =
> GeoPolygonFactory.makeLargeGeoPolygon(PlanetModel.SPHERE,
> Collections.singletonList(description));
> +
> +    //POINT(9.020991048228685E-4 -2.5357127427108625E-98)
> +    final GeoPoint point = new GeoPoint(PlanetModel.SPHERE,
> Geo3DUtil.fromDegrees(-2.5357127427108625E-98),
> Geo3DUtil.fromDegrees(9.020991048228685E-4));
> +    assertTrue(polygon.isWithin(point) == largePolygon.isWithin(point));
> +  }
>
> +  @Test
> +  @AwaitsFix(bugUrl="https://issues.apache.org/jira/browse/LUCENE-8276")
> +  public void testLUCENE8276_case3() {
> +    //POLYGON((2.693381024483753E-4
> -0.001073608118084019,1.5848404608659423E-4
> -2.6378130512803985E-4,8.981079660799132E-4
> -6.4697719116416E-4,-7.934854852157693E-5 4.193687767358618E-4,0.0
> 8.013660459916381E-131,-3.968797970346633E-4
> 3.2057826073172334E-4,2.693381024483753E-4 -0.001073608118084019))
> +    final List<GeoPoint> points = new ArrayList<>();
> +    points.add(new GeoPoint(PlanetModel.SPHERE,
> Geo3DUtil.fromDegrees(-0.001073608118084019),
> Geo3DUtil.fromDegrees(2.693381024483753E-4)));
> +    points.add(new GeoPoint(PlanetModel.SPHERE,
> Geo3DUtil.fromDegrees(-2.6378130512803985E-4),
> Geo3DUtil.fromDegrees(1.5848404608659423E-4)));
> +    points.add(new GeoPoint(PlanetModel.SPHERE,
> Geo3DUtil.fromDegrees(-6.4697719116416E-4),
> Geo3DUtil.fromDegrees(8.981079660799132E-4)));
> +    points.add(new GeoPoint(PlanetModel.SPHERE,
> Geo3DUtil.fromDegrees(4.193687767358618E-4),
> Geo3DUtil.fromDegrees(-7.934854852157693E-5)));
> +    points.add(new GeoPoint(PlanetModel.SPHERE,
> Geo3DUtil.fromDegrees(8.013660459916381E-131), Geo3DUtil.fromDegrees(0.0)));
> +    points.add(new GeoPoint(PlanetModel.SPHERE,
> Geo3DUtil.fromDegrees(3.2057826073172334E-4),
> Geo3DUtil.fromDegrees(-3.968797970346633E-4)));
> +    final GeoPolygonFactory.PolygonDescription description = new
> GeoPolygonFactory.PolygonDescription(points);
> +    final GeoPolygon polygon =
> GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE, description);
> +    final GeoPolygon largePolygon =
> GeoPolygonFactory.makeLargeGeoPolygon(PlanetModel.SPHERE,
> Collections.singletonList(description));
>
> +    //POINT(-2.394808631784144E-4 5.7E-322)
> +    final GeoPoint point = new GeoPoint(PlanetModel.SPHERE,
> Geo3DUtil.fromDegrees(5.7E-322),
> Geo3DUtil.fromDegrees(-2.394808631784144E-4));
> +    assertTrue(polygon.isWithin(point) == largePolygon.isWithin(point));
> +  }
>  }
>
>
> http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/8e029816/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/RandomGeoPolygonTest.java
> ----------------------------------------------------------------------
> diff --git
> a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/RandomGeoPolygonTest.java
> b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/RandomGeoPolygonTest.java
> index a181d17..25b518c 100644
> ---
> a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/RandomGeoPolygonTest.java
> +++
> b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/RandomGeoPolygonTest.java
> @@ -77,120 +77,152 @@ public class RandomGeoPolygonTest extends
> RandomGeo3dShapeGenerator {
>    public void testCoplanarityTilePolygon() {
>      //POLYGON((-90.55764 -0.34907,-90.55751 -0.34868,-90.55777
> -0.34842,-90.55815 -0.34766,-90.55943 -0.34842, -90.55918
> -0.34842,-90.55764 -0.34907))
>      List<GeoPoint> points = new ArrayList<>();
> -    points.add(new GeoPoint(PlanetModel.SPHERE, fromDegrees(-0.34907),
> fromDegrees(-90.55764)));
> -    points.add(new GeoPoint(PlanetModel.SPHERE, fromDegrees(-0.34868),
> fromDegrees(-90.55751)));
> -    points.add(new GeoPoint(PlanetModel.SPHERE, fromDegrees(-0.34842),
> fromDegrees(-90.55777)));
> -    points.add(new GeoPoint(PlanetModel.SPHERE, fromDegrees(-0.34766),
> fromDegrees(-90.55815)));
> -    points.add(new GeoPoint(PlanetModel.SPHERE, fromDegrees(-0.34842),
> fromDegrees(-90.55943)));
> -    points.add(new GeoPoint(PlanetModel.SPHERE, fromDegrees(-0.34842),
> fromDegrees(-90.55918)));
> +    points.add(new GeoPoint(PlanetModel.SPHERE,
> Geo3DUtil.fromDegrees(-0.34907), Geo3DUtil.fromDegrees(-90.55764)));
> +    points.add(new GeoPoint(PlanetModel.SPHERE,
> Geo3DUtil.fromDegrees(-0.34868), Geo3DUtil.fromDegrees(-90.55751)));
> +    points.add(new GeoPoint(PlanetModel.SPHERE,
> Geo3DUtil.fromDegrees(-0.34842), Geo3DUtil.fromDegrees(-90.55777)));
> +    points.add(new GeoPoint(PlanetModel.SPHERE,
> Geo3DUtil.fromDegrees(-0.34766), Geo3DUtil.fromDegrees(-90.55815)));
> +    points.add(new GeoPoint(PlanetModel.SPHERE,
> Geo3DUtil.fromDegrees(-0.34842), Geo3DUtil.fromDegrees(-90.55943)));
> +    points.add(new GeoPoint(PlanetModel.SPHERE,
> Geo3DUtil.fromDegrees(-0.34842), Geo3DUtil.fromDegrees(-90.55918)));
>      GeoCompositePolygon polygon =
> (GeoCompositePolygon)GeoPolygonFactory.makeGeoPolygon(PlanetModel.SPHERE,
> points);
>      assertTrue(polygon.size() == 3);
>    }
>
>    /**
> -   * Test comparing different polygon technologies using random
> +   * Test comparing different polygon (Big) technologies using random
>     * biased doubles.
>     */
>    @Test
>    @Repeat(iterations = 10)
> -  public void testComparePolygons() {
> +  public void testCompareBigPolygons() {
> +    testComparePolygons(Math.PI);
> +  }
> +
> +  /**
> +   * Test comparing different polygon (Small) technologies using random
> +   * biased doubles.
> +   */
> +  @Test
> +  @Repeat(iterations = 10)
> +  public void testCompareSmallPolygons() {
> +    testComparePolygons(1e-4 * Math.PI);
> +  }
> +
> +
> +  private void testComparePolygons(double limitDistance) {
>      final PlanetModel planetModel = randomPlanetModel();
>      //Create polygon points using a reference point and a maximum
> distance to the point
> -    final GeoPoint referencePoint = getBiasedPoint(planetModel);
> +    final GeoPoint referencePoint;
> +    if (random().nextBoolean()) {
> +     referencePoint = getBiasedPoint(planetModel);
> +    } else {
> +      referencePoint = randomGeoPoint(planetModel);
> +    }
>      final int n = random().nextInt(4) + 4;
>      final List<GeoPoint> points = new ArrayList<>(n);
> -    final double maxDistance = random().nextDouble() *  Math.PI;
> -    for (int i = 0; i < n; i++) {
> -      while(true) {
> -        final double distance =
> BiasedNumbers.randomDoubleBetween(random(), 0, maxDistance);//
> random().nextDouble() * maxDistance;
> -        final double bearing = random().nextDouble() * 2 * Math.PI;
> -        GeoPoint p = planetModel.surfacePointOnBearing(referencePoint,
> distance, bearing);
> -        if (!contains(p, points)) {
> -          if (points.size() > 1 &&
> Plane.arePointsCoplanar(points.get(points.size() -1),
> points.get(points.size() - 2), p)) {
> -            continue;
> +    List<GeoPoint> orderedPoints = null;
> +    GeoPolygon polygon = null;
> +    GeoPolygon largePolygon = null;
> +    do {
> +      double maxDistance = random().nextDouble() * limitDistance;
> +      //if distance is too small we can fail
> +      //building the polygon.
> +      while (maxDistance < 1e-7) {
> +        maxDistance = random().nextDouble() * limitDistance;
> +      }
> +      for (int i = 0; i < n; i++) {
> +        while (true) {
> +          final double distance =
> BiasedNumbers.randomDoubleBetween(random(), 0, maxDistance);//
> random().nextDouble() * maxDistance;
> +          final double bearing = random().nextDouble() * 2 * Math.PI;
> +          final GeoPoint p =
> planetModel.surfacePointOnBearing(referencePoint, distance, bearing);
> +          if (!contains(p, points)) {
> +            if (points.size() > 1 &&
> Plane.arePointsCoplanar(points.get(points.size() - 1),
> points.get(points.size() - 2), p)) {
> +              continue;
> +            }
> +            points.add(p);
> +            break;
>            }
> -          points.add(p);
> -          break;
>          }
>        }
> +      //order points so we don't get crossing edges
> +      orderedPoints = orderPoints(points);
> +      if (random().nextBoolean() && random().nextBoolean()) {
> +        Collections.reverse(orderedPoints);
> +      }
> +      final GeoPolygonFactory.PolygonDescription polygonDescription = new
> GeoPolygonFactory.PolygonDescription(orderedPoints);
> +
> +      try {
> +        polygon = GeoPolygonFactory.makeGeoPolygon(planetModel,
> polygonDescription);
> +      } catch (Exception e) {
> +        final StringBuilder buffer = new StringBuilder("Polygon failed to
> build with an exception:\n");
> +        buffer.append(points.toString() + "\n");
> +        buffer.append("WKT:" + getWKT(orderedPoints));
> +        buffer.append(e.toString());
> +        fail(buffer.toString());
> +      }
> +      if (polygon == null) {
> +        final StringBuilder buffer = new StringBuilder("Polygon failed to
> build:\n");
> +        buffer.append(points.toString() + "\n");
> +        buffer.append("WKT:" + getWKT(orderedPoints));
> +        fail(buffer.toString());
> +      }
> +      try {
> +        largePolygon = GeoPolygonFactory.makeLargeGeoPolygon(planetModel,
> Collections.singletonList(polygonDescription));
> +      } catch (Exception e) {
> +        final StringBuilder buffer = new StringBuilder("Large polygon
> failed to build with an exception:\n");
> +        buffer.append(points.toString() + "\n");
> +        buffer.append("WKT:" + getWKT(orderedPoints));
> +        buffer.append(e.toString());
> +        fail(buffer.toString());
> +      }
> +      if (largePolygon == null) {
> +        StringBuilder buffer = new StringBuilder("Large polygon failed to
> build:\n");
> +        buffer.append(points.toString() + "\n");
> +        buffer.append("WKT:" + getWKT(orderedPoints));
> +        fail(buffer.toString());
> +      }
> +    } while(polygon.getClass().equals(largePolygon.getClass()));
> +    //Some of these do not work but it seems it s from the way the point
> is created
> +    //GeoPoint centerOfMass = getCenterOfMass(planetModel, orderedPoints);
> +    //checkPoint(polygon, largePolygon, centerOfMass, orderedPoints);
> +    //checkPoint(polygon, largePolygon, new GeoPoint(-centerOfMass.x,
> -centerOfMass.y, -centerOfMass.z), orderedPoints);
> +    //checkPoint(polygon, largePolygon, new GeoPoint(centerOfMass.x,
> -centerOfMass.y, -centerOfMass.z), orderedPoints);
> +    //checkPoint(polygon, largePolygon, new GeoPoint(centerOfMass.x,
> centerOfMass.y, -centerOfMass.z), orderedPoints);
> +    //checkPoint(polygon, largePolygon, new GeoPoint(-centerOfMass.x,
> -centerOfMass.y, centerOfMass.z), orderedPoints);
> +    //checkPoint(polygon, largePolygon, new GeoPoint(-centerOfMass.x,
> centerOfMass.y, -centerOfMass.z), orderedPoints);
> +    //checkPoint(polygon, largePolygon, new GeoPoint(centerOfMass.x,
> -centerOfMass.y, centerOfMass.z), orderedPoints);
> +    for(int i = 0; i < 100000; i++) {
> +      final GeoPoint point;
> +      if (random().nextBoolean()) {
> +        point = getBiasedPoint(planetModel);
> +      } else {
> +        point = randomGeoPoint(planetModel);
> +      }
> +      checkPoint(polygon, largePolygon, point, orderedPoints);
>      }
> -    //order points so we don't get crossing edges
> -    final List<GeoPoint> orderedPoints = orderPoints(points);
> -    //Comment out below to get clock-wise polygons
> -    if (random().nextBoolean() && random().nextBoolean()) {
> -      Collections.reverse(orderedPoints);
> -    }
> -    GeoPolygonFactory.PolygonDescription polygonDescription = new
> GeoPolygonFactory.PolygonDescription(orderedPoints);
> -    GeoPolygon polygon = null;
> -    try {
> -      polygon = GeoPolygonFactory.makeGeoPolygon(planetModel,
> polygonDescription);
> -    } catch(Exception e) {
> -      StringBuilder buffer = new StringBuilder("Polygon failed to build
> with an exception:\n");
> -      buffer.append(points.toString()+ "\n");
> -      buffer.append("WKT:" + getWKT(orderedPoints));
> -      buffer.append(e.toString());
> -      fail(buffer.toString());
> -    }
> -    if (polygon == null) {
> -      StringBuilder buffer = new StringBuilder("Polygon failed to
> build:\n");
> -      buffer.append(points.toString()+ "\n");
> -      buffer.append("WKT:" + getWKT(orderedPoints));
> -      fail(buffer.toString());
> -    }
> -    GeoPolygon largePolygon = null;
> -    try {
> -      largePolygon = GeoPolygonFactory.makeLargeGeoPolygon(planetModel,
> Collections.singletonList(polygonDescription));
> -    } catch(Exception e) {
> -      StringBuilder buffer = new StringBuilder("Large polygon failed to
> build with an exception:\n");
> -      buffer.append(points.toString()+ "\n");
> -      buffer.append("WKT:" + getWKT(orderedPoints));
> -      buffer.append(e.toString());
> -      fail(buffer.toString());
> -    }
> -    if (largePolygon == null) {
> -      StringBuilder buffer = new StringBuilder("Large polygon failed to
> build:\n");
> -      buffer.append(points.toString()+ "\n");
> -      buffer.append("WKT:" + getWKT(orderedPoints));
> -      fail(buffer.toString());
> -    }
> +  }
>
> -    for(int i=0;i<100000;i++) {
> -      GeoPoint point = getBiasedPoint(planetModel);
> -      boolean withIn1 = polygon.isWithin(point);
> -      boolean withIn2 = largePolygon.isWithin(point);
> -      StringBuilder buffer = new StringBuilder();
> -      if (withIn1 != withIn2) {
> -        //NOTE: Sometimes we get errors when check point is near a
> polygon point.
> -        // For the time being, we filter this errors.
> -        double d1 = polygon.computeOutsideDistance(DistanceStyle.ARC,
> point);
> -        double d2  =
> largePolygon.computeOutsideDistance(DistanceStyle.ARC, point);
> -        if (d1 == 0 && d2 == 0) {
> -          continue;
> -        }
> -        buffer = buffer.append("\nStandard polygon: " +
> polygon.toString() +"\n");
> -        buffer = buffer.append("\nLarge polygon: " +
> largePolygon.toString() +"\n");
> -        buffer = buffer.append("\nPoint: " + point.toString() +"\n");
> -        buffer.append("\nWKT: " + getWKT(orderedPoints));
> -        buffer.append("\nWKT: POINT(" + toDegrees(point.getLongitude()) +
> " " + toDegrees(point.getLatitude()) + ")\n");
> -        buffer.append("normal polygon: " +withIn1 + "\n");
> -        buffer.append("large polygon: " + withIn2 + "\n");
> +  private void checkPoint(final GeoPolygon polygon, final GeoPolygon
> largePolygon, final GeoPoint point, final List<GeoPoint> orderedPoints) {
> +    final boolean withIn1 = polygon.isWithin(point);
> +    final boolean withIn2 = largePolygon.isWithin(point);
> +    StringBuilder buffer = new StringBuilder();
> +    if (withIn1 != withIn2) {
> +      //NOTE: Standard and large polygon are mathematically slightly
> different
> +      //close to the edges (due to bounding planes). Nothing we can do
> about that
> +      //so we filter the differences.
> +      final double d1 = polygon.computeOutsideDistance(DistanceStyle.ARC,
> point);
> +      final double d2  =
> largePolygon.computeOutsideDistance(DistanceStyle.ARC, point);
> +      if (d1 == 0 && d2 == 0) {
> +        return;
>        }
> -      assertTrue(buffer.toString(), withIn1 == withIn2);
> +      buffer = buffer.append("\nStandard polygon: " + polygon.toString()
> +"\n");
> +      buffer = buffer.append("\nLarge polygon: " +
> largePolygon.toString() +"\n");
> +      buffer = buffer.append("\nPoint: " + point.toString() +"\n");
> +      buffer.append("\nWKT: " + getWKT(orderedPoints));
> +      buffer.append("\nWKT: POINT(" +
> Geo3DUtil.toDegrees(point.getLongitude()) + " " +
> Geo3DUtil.toDegrees(point.getLatitude()) + ")\n");
> +      buffer.append("normal polygon: " +withIn1 + "\n");
> +      buffer.append("large polygon: " + withIn2 + "\n");
>      }
> -    //Not yet tested
> -//    for(int i=0;i<100;i++) {
> -//      GeoShape shape = randomGeoShape(randomShapeType(), planetModel);
> -//      int rel1 = polygon.getRelationship(shape);
> -//      int rel2 = largePolygon.getRelationship(shape);
> -//      StringBuilder buffer = new StringBuilder();
> -//      if (rel1 != rel2) {
> -//        buffer = buffer.append(polygon.toString() +"\n" +
> shape.toString() + "\n");
> -//        buffer.append("WKT: " + getWKT(orderedPoints) + "\n");
> -//        buffer.append("normal polygon: " + rel1 + "\n");
> -//        buffer.append("large polygon: " + rel2 + "\n");
> -//      }
> -//      assertTrue(buffer.toString(), rel1 == rel2);
> -//    }
> +    assertTrue(buffer.toString(), withIn1 == withIn2);
>    }
>
>    private GeoPoint getBiasedPoint(PlanetModel planetModel) {
> @@ -208,9 +240,9 @@ public class RandomGeoPolygonTest extends
> RandomGeo3dShapeGenerator {
>    private String getWKT(List<GeoPoint> points) {
>      StringBuffer buffer = new StringBuffer("POLYGON((");
>      for (GeoPoint point : points) {
> -      buffer.append(toDegrees(point.getLongitude()) + " " +
> toDegrees(point.getLatitude()) + ",");
> +      buffer.append(Geo3DUtil.toDegrees(point.getLongitude()) + " " +
> Geo3DUtil.toDegrees(point.getLatitude()) + ",");
>      }
> -    buffer.append(toDegrees(points.get(0).getLongitude()) + " " +
> toDegrees(points.get(0).getLatitude()) + "))\n");
> +    buffer.append(Geo3DUtil.toDegrees(points.get(0).getLongitude()) + " "
> + Geo3DUtil.toDegrees(points.get(0).getLatitude()) + "))\n");
>      return buffer.toString();
>    }
>
> @@ -222,18 +254,19 @@ public class RandomGeoPolygonTest extends
> RandomGeo3dShapeGenerator {
>      }
>      return false;
>    }
> -
> -  final private static double DEGREES_PER_RADIAN = 180.0 / Math.PI;
> -  final private static double RADIANS_PER_DEGREE = Math.PI / 180.0;
> -
> -  /** Converts radians to degrees */
> -  private static double toDegrees(final double radians) {
> -    return radians * DEGREES_PER_RADIAN;
> -  }
>
> -  /** Converts radians to degrees */
> -  private static double fromDegrees(final double degrees) {
> -    return degrees * RADIANS_PER_DEGREE;
> +  private GeoPoint getCenterOfMass(final PlanetModel planetModel, final
> List<GeoPoint> points) {
> +    double x = 0;
> +    double y = 0;
> +    double z = 0;
> +    //get center of mass
> +    for (final GeoPoint point : points) {
> +      x += point.x;
> +      y += point.y;
> +      z += point.z;
> +    }
> +    // Normalization is not needed because createSurfacePoint does the
> scaling anyway.
> +    return planetModel.createSurfacePoint(x, y, z);
>    }
>
>  }
>
>