@Test
public void testCreateHullFromGeometry() {

  final GeometryHullTool cg = new GeometryHullTool();
  cg.setDistanceFnForCoordinate(new CoordinateCircleDistanceFn());
  for (int i = 2; i < 10; i++) {
    final Coordinate[] coords = new Coordinate[i];
    for (int p = 0; p < i; p++) {
      coords[p] = new Coordinate(p, p);
    }
    final Geometry lineString1 = factory.createLineString(coords);
    final Geometry concaveHull1 =
        cg.createHullFromGeometry(lineString1, Arrays.asList(coords[0]), true);
    assertEquals(
        "straigh line size=" + i + " geo=" + lineString1.toText(),
        2,
        concaveHull1.getCoordinates().length);
  }
  final Geometry lineString3 =
      factory.createLineString(
          new Coordinate[] {new Coordinate(1, 1), new Coordinate(2, 2), new Coordinate(3, 1)});
  final Geometry concaveHull3 =
      cg.createHullFromGeometry(
          lineString3,
          Arrays.asList(lineString3.getCoordinates()[0]),
          true);
  assertEquals(
      "expecting a triangle " + concaveHull3.toText(),
      4,
      concaveHull3.getCoordinates().length);
  assertTrue("expecting a triangle " + concaveHull3.toText(), concaveHull3.getArea() > 0.0);
  assertTrue(concaveHull3.isSimple());
  assertEquals(
      "expecting identical result",
      lineString3,
      cg.createHullFromGeometry(lineString3, Collections.<Coordinate>emptyList(), true));
  final Geometry[] newPoints = new Geometry[900];
  for (int j = 0; j < 10; j++) {
    final Coordinate[] newCoords = new Coordinate[900];
    final Coordinate[] geoCoords = new Coordinate[100];
    final Random rand = new Random(73634 + j);
    for (int i = 0; i < 100; i++) {
      geoCoords[i] = new Coordinate(rand.nextGaussian() * 0.001, rand.nextGaussian() * 0.001);
    }
    for (int i = 0; i < 900; i++) {
      newCoords[i] = new Coordinate(rand.nextGaussian() * 0.01, rand.nextGaussian() * 0.01);
      newPoints[i] = factory.createPoint(newCoords[i]);
    }
    final ConvexHull hull = new ConvexHull(geoCoords, factory);
    final Geometry concaveHull =
        cg.createHullFromGeometry(hull.getConvexHull(), Arrays.asList(newCoords), true);
    assertTrue(concaveHull.isSimple());
    int error = 0;
    for (final Geometry newPoint : newPoints) {
      error += concaveHull.intersects(newPoint) ? 0 : 1;
    }
    assertTrue(error < 3);
    final Geometry concaveHull2 =
        cg.createHullFromGeometry(hull.getConvexHull(), Arrays.asList(newCoords), false);
    assertTrue(concaveHull2.isSimple());
    error = 0;
    for (final Geometry newPoint : newPoints) {
      error += concaveHull2.intersects(newPoint) ? 0 : 1;
    }
    assertTrue(error < 1);
  }
}