package com.revolsys.geometry.test.old.perf.algorithm;
import com.revolsys.geometry.model.GeometryFactory;
import com.revolsys.geometry.model.LinearRing;
import com.revolsys.geometry.model.Point;
import com.revolsys.geometry.model.Polygon;
import com.revolsys.geometry.model.impl.PointDoubleXY;
public class AreaPrecisionPerfTest {
public static double accurateSignedArea(final Point[] ring) {
if (ring.length < 3) {
return 0.0;
}
double sum = 0.0;
// http://en.wikipedia.org/wiki/Shoelace_formula
final double x0 = ring[0].getX();
for (int i = 1; i < ring.length - 1; i++) {
final double x = ring[i].getX() - x0;
final double y1 = ring[i + 1].getY();
final double y2 = ring[i == 0 ? ring.length - 1 : i - 1].getY();
sum += x * (y2 - y1);
}
return sum / 2.0;
}
public static void main(final String[] args) throws Exception {
final double originX = 1000000;
final double originY = 5000000;
final long start = System.currentTimeMillis();
for (int nrVertices = 4; nrVertices <= 1000000; nrVertices *= 2) {
final Point[] coordinates = new Point[nrVertices + 1];
Point vertex;
for (int i = 0; i <= nrVertices; i++) {
vertex = new PointDoubleXY(
originX + (1 + Math.sin((float)i / (float)nrVertices * 2 * Math.PI)),
originY + (1 + Math.cos((float)i / (float)nrVertices * 2 * Math.PI)));
coordinates[i] = vertex;
}
// close ring
coordinates[nrVertices] = coordinates[0];
final LinearRing g1 = GeometryFactory.DEFAULT_3D.linearRing(coordinates);
final Polygon polygon = GeometryFactory.DEFAULT_3D.polygon(g1);
// System.out.println(polygon);
final double area = originalSignedArea(coordinates);
final double area2 = accurateSignedArea(coordinates);
final double exactArea = 0.5 * nrVertices * Math.sin(2 * Math.PI / nrVertices);
final double eps = exactArea - area;
final double eps2 = exactArea - area2;
// System.out.println(nrVertices + " orig err: " + eps + " acc err: "
// + eps2);
}
// System.out.println("Time: " + (System.currentTimeMillis() - start) /
// 1000.0);
}
public static double originalSignedArea(final Point[] ring) {
if (ring.length < 3) {
return 0.0;
}
double sum = 0.0;
for (int i = 0; i < ring.length - 1; i++) {
final double bx = ring[i].getX();
final double by = ring[i].getY();
final double cx = ring[i + 1].getX();
final double cy = ring[i + 1].getY();
sum += (bx + cx) * (cy - by);
}
return -sum / 2.0;
}
}