mirror of https://github.com/apache/lucene.git
LUCENE-7241: Get rid of one more allocation during isWithin processing.
This commit is contained in:
parent
49b3eee4c8
commit
1fdc2b9880
|
@ -119,38 +119,33 @@ class GeoComplexPolygon extends GeoBasePolygon {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isWithin(final double x, final double y, final double z) {
|
public boolean isWithin(final double x, final double y, final double z) {
|
||||||
return isWithin(new Vector(x, y, z));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isWithin(final Vector thePoint) {
|
|
||||||
// If we're right on top of the point, we know the answer.
|
// If we're right on top of the point, we know the answer.
|
||||||
if (testPoint.isNumericallyIdentical(thePoint)) {
|
if (testPoint.isNumericallyIdentical(x, y, z)) {
|
||||||
return testPointInSet;
|
return testPointInSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we're right on top of any of the test planes, we navigate solely on that plane.
|
// If we're right on top of any of the test planes, we navigate solely on that plane.
|
||||||
if (testPointFixedYPlane.evaluateIsZero(thePoint)) {
|
if (testPointFixedYPlane.evaluateIsZero(x, y, z)) {
|
||||||
// Use the XZ plane exclusively.
|
// Use the XZ plane exclusively.
|
||||||
final LinearCrossingEdgeIterator crossingEdgeIterator = new LinearCrossingEdgeIterator(testPointFixedYPlane, testPointFixedYAbovePlane, testPointFixedYBelowPlane, thePoint);
|
final LinearCrossingEdgeIterator crossingEdgeIterator = new LinearCrossingEdgeIterator(testPointFixedYPlane, testPointFixedYAbovePlane, testPointFixedYBelowPlane, x, y, z);
|
||||||
// Traverse our way from the test point to the check point. Use the y tree because that's fixed.
|
// Traverse our way from the test point to the check point. Use the y tree because that's fixed.
|
||||||
if (!yTree.traverse(crossingEdgeIterator, testPoint.y)) {
|
if (!yTree.traverse(crossingEdgeIterator, testPoint.y)) {
|
||||||
// Endpoint is on edge
|
// Endpoint is on edge
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return ((crossingEdgeIterator.crossingCount & 1) == 0)?testPointInSet:!testPointInSet;
|
return ((crossingEdgeIterator.crossingCount & 1) == 0)?testPointInSet:!testPointInSet;
|
||||||
} else if (testPointFixedXPlane.evaluateIsZero(thePoint)) {
|
} else if (testPointFixedXPlane.evaluateIsZero(x, y, z)) {
|
||||||
// Use the YZ plane exclusively.
|
// Use the YZ plane exclusively.
|
||||||
final LinearCrossingEdgeIterator crossingEdgeIterator = new LinearCrossingEdgeIterator(testPointFixedXPlane, testPointFixedXAbovePlane, testPointFixedXBelowPlane, thePoint);
|
final LinearCrossingEdgeIterator crossingEdgeIterator = new LinearCrossingEdgeIterator(testPointFixedXPlane, testPointFixedXAbovePlane, testPointFixedXBelowPlane, x, y, z);
|
||||||
// Traverse our way from the test point to the check point. Use the x tree because that's fixed.
|
// Traverse our way from the test point to the check point. Use the x tree because that's fixed.
|
||||||
if (!xTree.traverse(crossingEdgeIterator, testPoint.x)) {
|
if (!xTree.traverse(crossingEdgeIterator, testPoint.x)) {
|
||||||
// Endpoint is on edge
|
// Endpoint is on edge
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return ((crossingEdgeIterator.crossingCount & 1) == 0)?testPointInSet:!testPointInSet;
|
return ((crossingEdgeIterator.crossingCount & 1) == 0)?testPointInSet:!testPointInSet;
|
||||||
} else if (testPointFixedZPlane.evaluateIsZero(thePoint)) {
|
} else if (testPointFixedZPlane.evaluateIsZero(x, y, z)) {
|
||||||
// Use the XY plane exclusively.
|
// Use the XY plane exclusively.
|
||||||
final LinearCrossingEdgeIterator crossingEdgeIterator = new LinearCrossingEdgeIterator(testPointFixedZPlane, testPointFixedZAbovePlane, testPointFixedZBelowPlane, thePoint);
|
final LinearCrossingEdgeIterator crossingEdgeIterator = new LinearCrossingEdgeIterator(testPointFixedZPlane, testPointFixedZAbovePlane, testPointFixedZBelowPlane, x, y, z);
|
||||||
// Traverse our way from the test point to the check point. Use the z tree because that's fixed.
|
// Traverse our way from the test point to the check point. Use the z tree because that's fixed.
|
||||||
if (!zTree.traverse(crossingEdgeIterator, testPoint.z)) {
|
if (!zTree.traverse(crossingEdgeIterator, testPoint.z)) {
|
||||||
// Endpoint is on edge
|
// Endpoint is on edge
|
||||||
|
@ -163,9 +158,9 @@ class GeoComplexPolygon extends GeoBasePolygon {
|
||||||
// Changing the code below has an enormous impact on the queries per second we see with the benchmark.
|
// Changing the code below has an enormous impact on the queries per second we see with the benchmark.
|
||||||
|
|
||||||
// We need to use two planes to get there. We don't know which two planes will do it but we can figure it out.
|
// We need to use two planes to get there. We don't know which two planes will do it but we can figure it out.
|
||||||
final Plane travelPlaneFixedX = new Plane(1.0, 0.0, 0.0, -thePoint.x);
|
final Plane travelPlaneFixedX = new Plane(1.0, 0.0, 0.0, -x);
|
||||||
final Plane travelPlaneFixedY = new Plane(0.0, 1.0, 0.0, -thePoint.y);
|
final Plane travelPlaneFixedY = new Plane(0.0, 1.0, 0.0, -y);
|
||||||
final Plane travelPlaneFixedZ = new Plane(0.0, 0.0, 1.0, -thePoint.z);
|
final Plane travelPlaneFixedZ = new Plane(0.0, 0.0, 1.0, -z);
|
||||||
|
|
||||||
// Find the intersection points for each one of these and the complementary test point planes.
|
// Find the intersection points for each one of these and the complementary test point planes.
|
||||||
final GeoPoint[] XIntersectionsY = travelPlaneFixedX.findIntersections(planetModel, testPointFixedYPlane);
|
final GeoPoint[] XIntersectionsY = travelPlaneFixedX.findIntersections(planetModel, testPointFixedYPlane);
|
||||||
|
@ -193,15 +188,15 @@ class GeoComplexPolygon extends GeoBasePolygon {
|
||||||
//final double newDistance = p.arcDistance(testPoint) + p.arcDistance(thePoint);
|
//final double newDistance = p.arcDistance(testPoint) + p.arcDistance(thePoint);
|
||||||
final double tpDelta1 = testPoint.x - p.x;
|
final double tpDelta1 = testPoint.x - p.x;
|
||||||
final double tpDelta2 = testPoint.z - p.z;
|
final double tpDelta2 = testPoint.z - p.z;
|
||||||
final double cpDelta1 = thePoint.y - p.y;
|
final double cpDelta1 = y - p.y;
|
||||||
final double cpDelta2 = thePoint.z - p.z;
|
final double cpDelta2 = z - p.z;
|
||||||
final double newDistance = tpDelta1 * tpDelta1 + tpDelta2 * tpDelta2 + cpDelta1 * cpDelta1 + cpDelta2 * cpDelta2;
|
final double newDistance = tpDelta1 * tpDelta1 + tpDelta2 * tpDelta2 + cpDelta1 * cpDelta1 + cpDelta2 * cpDelta2;
|
||||||
//final double newDistance = (testPoint.x - p.x) * (testPoint.x - p.x) + (testPoint.z - p.z) * (testPoint.z - p.z) + (thePoint.y - p.y) * (thePoint.y - p.y) + (thePoint.z - p.z) * (thePoint.z - p.z);
|
//final double newDistance = (testPoint.x - p.x) * (testPoint.x - p.x) + (testPoint.z - p.z) * (testPoint.z - p.z) + (thePoint.y - p.y) * (thePoint.y - p.y) + (thePoint.z - p.z) * (thePoint.z - p.z);
|
||||||
//final double newDistance = Math.abs(testPoint.x - p.x) + Math.abs(thePoint.y - p.y);
|
//final double newDistance = Math.abs(testPoint.x - p.x) + Math.abs(thePoint.y - p.y);
|
||||||
if (newDistance < bestDistance) {
|
if (newDistance < bestDistance) {
|
||||||
bestDistance = newDistance;
|
bestDistance = newDistance;
|
||||||
firstLegValue = testPoint.y;
|
firstLegValue = testPoint.y;
|
||||||
secondLegValue = thePoint.x;
|
secondLegValue = x;
|
||||||
firstLegPlane = testPointFixedYPlane;
|
firstLegPlane = testPointFixedYPlane;
|
||||||
firstLegAbovePlane = testPointFixedYAbovePlane;
|
firstLegAbovePlane = testPointFixedYAbovePlane;
|
||||||
firstLegBelowPlane = testPointFixedYBelowPlane;
|
firstLegBelowPlane = testPointFixedYBelowPlane;
|
||||||
|
@ -216,15 +211,15 @@ class GeoComplexPolygon extends GeoBasePolygon {
|
||||||
//final double newDistance = p.arcDistance(testPoint) + p.arcDistance(thePoint);
|
//final double newDistance = p.arcDistance(testPoint) + p.arcDistance(thePoint);
|
||||||
final double tpDelta1 = testPoint.x - p.x;
|
final double tpDelta1 = testPoint.x - p.x;
|
||||||
final double tpDelta2 = testPoint.y - p.y;
|
final double tpDelta2 = testPoint.y - p.y;
|
||||||
final double cpDelta1 = thePoint.y - p.y;
|
final double cpDelta1 = y - p.y;
|
||||||
final double cpDelta2 = thePoint.z - p.z;
|
final double cpDelta2 = z - p.z;
|
||||||
final double newDistance = tpDelta1 * tpDelta1 + tpDelta2 * tpDelta2 + cpDelta1 * cpDelta1 + cpDelta2 * cpDelta2;
|
final double newDistance = tpDelta1 * tpDelta1 + tpDelta2 * tpDelta2 + cpDelta1 * cpDelta1 + cpDelta2 * cpDelta2;
|
||||||
//final double newDistance = (testPoint.x - p.x) * (testPoint.x - p.x) + (testPoint.y - p.y) * (testPoint.y - p.y) + (thePoint.y - p.y) * (thePoint.y - p.y) + (thePoint.z - p.z) * (thePoint.z - p.z);
|
//final double newDistance = (testPoint.x - p.x) * (testPoint.x - p.x) + (testPoint.y - p.y) * (testPoint.y - p.y) + (thePoint.y - p.y) * (thePoint.y - p.y) + (thePoint.z - p.z) * (thePoint.z - p.z);
|
||||||
//final double newDistance = Math.abs(testPoint.x - p.x) + Math.abs(thePoint.z - p.z);
|
//final double newDistance = Math.abs(testPoint.x - p.x) + Math.abs(thePoint.z - p.z);
|
||||||
if (newDistance < bestDistance) {
|
if (newDistance < bestDistance) {
|
||||||
bestDistance = newDistance;
|
bestDistance = newDistance;
|
||||||
firstLegValue = testPoint.z;
|
firstLegValue = testPoint.z;
|
||||||
secondLegValue = thePoint.x;
|
secondLegValue = x;
|
||||||
firstLegPlane = testPointFixedZPlane;
|
firstLegPlane = testPointFixedZPlane;
|
||||||
firstLegAbovePlane = testPointFixedZAbovePlane;
|
firstLegAbovePlane = testPointFixedZAbovePlane;
|
||||||
firstLegBelowPlane = testPointFixedZBelowPlane;
|
firstLegBelowPlane = testPointFixedZBelowPlane;
|
||||||
|
@ -239,15 +234,15 @@ class GeoComplexPolygon extends GeoBasePolygon {
|
||||||
//final double newDistance = p.arcDistance(testPoint) + p.arcDistance(thePoint);
|
//final double newDistance = p.arcDistance(testPoint) + p.arcDistance(thePoint);
|
||||||
final double tpDelta1 = testPoint.y - p.y;
|
final double tpDelta1 = testPoint.y - p.y;
|
||||||
final double tpDelta2 = testPoint.z - p.z;
|
final double tpDelta2 = testPoint.z - p.z;
|
||||||
final double cpDelta1 = thePoint.x - p.x;
|
final double cpDelta1 = x - p.x;
|
||||||
final double cpDelta2 = thePoint.z - p.z;
|
final double cpDelta2 = z - p.z;
|
||||||
final double newDistance = tpDelta1 * tpDelta1 + tpDelta2 * tpDelta2 + cpDelta1 * cpDelta1 + cpDelta2 * cpDelta2;
|
final double newDistance = tpDelta1 * tpDelta1 + tpDelta2 * tpDelta2 + cpDelta1 * cpDelta1 + cpDelta2 * cpDelta2;
|
||||||
//final double newDistance = (testPoint.y - p.y) * (testPoint.y - p.y) + (testPoint.z - p.z) * (testPoint.z - p.z) + (thePoint.x - p.x) * (thePoint.x - p.x) + (thePoint.z - p.z) * (thePoint.z - p.z);
|
//final double newDistance = (testPoint.y - p.y) * (testPoint.y - p.y) + (testPoint.z - p.z) * (testPoint.z - p.z) + (thePoint.x - p.x) * (thePoint.x - p.x) + (thePoint.z - p.z) * (thePoint.z - p.z);
|
||||||
//final double newDistance = Math.abs(testPoint.y - p.y) + Math.abs(thePoint.x - p.x);
|
//final double newDistance = Math.abs(testPoint.y - p.y) + Math.abs(thePoint.x - p.x);
|
||||||
if (newDistance < bestDistance) {
|
if (newDistance < bestDistance) {
|
||||||
bestDistance = newDistance;
|
bestDistance = newDistance;
|
||||||
firstLegValue = testPoint.x;
|
firstLegValue = testPoint.x;
|
||||||
secondLegValue = thePoint.y;
|
secondLegValue = y;
|
||||||
firstLegPlane = testPointFixedXPlane;
|
firstLegPlane = testPointFixedXPlane;
|
||||||
firstLegAbovePlane = testPointFixedXAbovePlane;
|
firstLegAbovePlane = testPointFixedXAbovePlane;
|
||||||
firstLegBelowPlane = testPointFixedXBelowPlane;
|
firstLegBelowPlane = testPointFixedXBelowPlane;
|
||||||
|
@ -262,15 +257,15 @@ class GeoComplexPolygon extends GeoBasePolygon {
|
||||||
//final double newDistance = p.arcDistance(testPoint) + p.arcDistance(thePoint);
|
//final double newDistance = p.arcDistance(testPoint) + p.arcDistance(thePoint);
|
||||||
final double tpDelta1 = testPoint.x - p.x;
|
final double tpDelta1 = testPoint.x - p.x;
|
||||||
final double tpDelta2 = testPoint.y - p.y;
|
final double tpDelta2 = testPoint.y - p.y;
|
||||||
final double cpDelta1 = thePoint.x - p.x;
|
final double cpDelta1 = x - p.x;
|
||||||
final double cpDelta2 = thePoint.z - p.z;
|
final double cpDelta2 = z - p.z;
|
||||||
final double newDistance = tpDelta1 * tpDelta1 + tpDelta2 * tpDelta2 + cpDelta1 * cpDelta1 + cpDelta2 * cpDelta2;
|
final double newDistance = tpDelta1 * tpDelta1 + tpDelta2 * tpDelta2 + cpDelta1 * cpDelta1 + cpDelta2 * cpDelta2;
|
||||||
//final double newDistance = (testPoint.x - p.x) * (testPoint.x - p.x) + (testPoint.y - p.y) * (testPoint.y - p.y) + (thePoint.x - p.x) * (thePoint.x - p.x) + (thePoint.z - p.z) * (thePoint.z - p.z);
|
//final double newDistance = (testPoint.x - p.x) * (testPoint.x - p.x) + (testPoint.y - p.y) * (testPoint.y - p.y) + (thePoint.x - p.x) * (thePoint.x - p.x) + (thePoint.z - p.z) * (thePoint.z - p.z);
|
||||||
//final double newDistance = Math.abs(testPoint.y - p.y) + Math.abs(thePoint.z - p.z);
|
//final double newDistance = Math.abs(testPoint.y - p.y) + Math.abs(thePoint.z - p.z);
|
||||||
if (newDistance < bestDistance) {
|
if (newDistance < bestDistance) {
|
||||||
bestDistance = newDistance;
|
bestDistance = newDistance;
|
||||||
firstLegValue = testPoint.z;
|
firstLegValue = testPoint.z;
|
||||||
secondLegValue = thePoint.y;
|
secondLegValue = y;
|
||||||
firstLegPlane = testPointFixedZPlane;
|
firstLegPlane = testPointFixedZPlane;
|
||||||
firstLegAbovePlane = testPointFixedZAbovePlane;
|
firstLegAbovePlane = testPointFixedZAbovePlane;
|
||||||
firstLegBelowPlane = testPointFixedZBelowPlane;
|
firstLegBelowPlane = testPointFixedZBelowPlane;
|
||||||
|
@ -285,15 +280,15 @@ class GeoComplexPolygon extends GeoBasePolygon {
|
||||||
//final double newDistance = p.arcDistance(testPoint) + p.arcDistance(thePoint);
|
//final double newDistance = p.arcDistance(testPoint) + p.arcDistance(thePoint);
|
||||||
final double tpDelta1 = testPoint.y - p.y;
|
final double tpDelta1 = testPoint.y - p.y;
|
||||||
final double tpDelta2 = testPoint.z - p.z;
|
final double tpDelta2 = testPoint.z - p.z;
|
||||||
final double cpDelta1 = thePoint.y - p.y;
|
final double cpDelta1 = y - p.y;
|
||||||
final double cpDelta2 = thePoint.x - p.x;
|
final double cpDelta2 = x - p.x;
|
||||||
final double newDistance = tpDelta1 * tpDelta1 + tpDelta2 * tpDelta2 + cpDelta1 * cpDelta1 + cpDelta2 * cpDelta2;
|
final double newDistance = tpDelta1 * tpDelta1 + tpDelta2 * tpDelta2 + cpDelta1 * cpDelta1 + cpDelta2 * cpDelta2;
|
||||||
//final double newDistance = (testPoint.y - p.y) * (testPoint.y - p.y) + (testPoint.z - p.z) * (testPoint.z - p.z) + (thePoint.y - p.y) * (thePoint.y - p.y) + (thePoint.x - p.x) * (thePoint.x - p.x);
|
//final double newDistance = (testPoint.y - p.y) * (testPoint.y - p.y) + (testPoint.z - p.z) * (testPoint.z - p.z) + (thePoint.y - p.y) * (thePoint.y - p.y) + (thePoint.x - p.x) * (thePoint.x - p.x);
|
||||||
//final double newDistance = Math.abs(testPoint.z - p.z) + Math.abs(thePoint.x - p.x);
|
//final double newDistance = Math.abs(testPoint.z - p.z) + Math.abs(thePoint.x - p.x);
|
||||||
if (newDistance < bestDistance) {
|
if (newDistance < bestDistance) {
|
||||||
bestDistance = newDistance;
|
bestDistance = newDistance;
|
||||||
firstLegValue = testPoint.x;
|
firstLegValue = testPoint.x;
|
||||||
secondLegValue = thePoint.z;
|
secondLegValue = z;
|
||||||
firstLegPlane = testPointFixedXPlane;
|
firstLegPlane = testPointFixedXPlane;
|
||||||
firstLegAbovePlane = testPointFixedXAbovePlane;
|
firstLegAbovePlane = testPointFixedXAbovePlane;
|
||||||
firstLegBelowPlane = testPointFixedXBelowPlane;
|
firstLegBelowPlane = testPointFixedXBelowPlane;
|
||||||
|
@ -308,15 +303,15 @@ class GeoComplexPolygon extends GeoBasePolygon {
|
||||||
//final double newDistance = p.arcDistance(testPoint) + p.arcDistance(thePoint);
|
//final double newDistance = p.arcDistance(testPoint) + p.arcDistance(thePoint);
|
||||||
final double tpDelta1 = testPoint.x - p.x;
|
final double tpDelta1 = testPoint.x - p.x;
|
||||||
final double tpDelta2 = testPoint.z - p.z;
|
final double tpDelta2 = testPoint.z - p.z;
|
||||||
final double cpDelta1 = thePoint.y - p.y;
|
final double cpDelta1 = y - p.y;
|
||||||
final double cpDelta2 = thePoint.x - p.x;
|
final double cpDelta2 = x - p.x;
|
||||||
final double newDistance = tpDelta1 * tpDelta1 + tpDelta2 * tpDelta2 + cpDelta1 * cpDelta1 + cpDelta2 * cpDelta2;
|
final double newDistance = tpDelta1 * tpDelta1 + tpDelta2 * tpDelta2 + cpDelta1 * cpDelta1 + cpDelta2 * cpDelta2;
|
||||||
//final double newDistance = (testPoint.x - p.x) * (testPoint.x - p.x) + (testPoint.z - p.z) * (testPoint.z - p.z) + (thePoint.y - p.y) * (thePoint.y - p.y) + (thePoint.x - p.x) * (thePoint.x - p.x);
|
//final double newDistance = (testPoint.x - p.x) * (testPoint.x - p.x) + (testPoint.z - p.z) * (testPoint.z - p.z) + (thePoint.y - p.y) * (thePoint.y - p.y) + (thePoint.x - p.x) * (thePoint.x - p.x);
|
||||||
//final double newDistance = Math.abs(testPoint.z - p.z) + Math.abs(thePoint.y - p.y);
|
//final double newDistance = Math.abs(testPoint.z - p.z) + Math.abs(thePoint.y - p.y);
|
||||||
if (newDistance < bestDistance) {
|
if (newDistance < bestDistance) {
|
||||||
bestDistance = newDistance;
|
bestDistance = newDistance;
|
||||||
firstLegValue = testPoint.y;
|
firstLegValue = testPoint.y;
|
||||||
secondLegValue = thePoint.z;
|
secondLegValue = z;
|
||||||
firstLegPlane = testPointFixedYPlane;
|
firstLegPlane = testPointFixedYPlane;
|
||||||
firstLegAbovePlane = testPointFixedYAbovePlane;
|
firstLegAbovePlane = testPointFixedYAbovePlane;
|
||||||
firstLegBelowPlane = testPointFixedYBelowPlane;
|
firstLegBelowPlane = testPointFixedYBelowPlane;
|
||||||
|
@ -330,7 +325,7 @@ class GeoComplexPolygon extends GeoBasePolygon {
|
||||||
assert bestDistance > 0.0 : "Best distance should not be zero unless on single plane";
|
assert bestDistance > 0.0 : "Best distance should not be zero unless on single plane";
|
||||||
assert bestDistance < Double.MAX_VALUE : "Couldn't find an intersection point of any kind";
|
assert bestDistance < Double.MAX_VALUE : "Couldn't find an intersection point of any kind";
|
||||||
|
|
||||||
final DualCrossingEdgeIterator edgeIterator = new DualCrossingEdgeIterator(firstLegPlane, firstLegAbovePlane, firstLegBelowPlane, secondLegPlane, thePoint, intersectionPoint);
|
final DualCrossingEdgeIterator edgeIterator = new DualCrossingEdgeIterator(firstLegPlane, firstLegAbovePlane, firstLegBelowPlane, secondLegPlane, x, y, z, intersectionPoint);
|
||||||
if (!firstLegTree.traverse(edgeIterator, firstLegValue)) {
|
if (!firstLegTree.traverse(edgeIterator, firstLegValue)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -708,23 +703,27 @@ class GeoComplexPolygon extends GeoBasePolygon {
|
||||||
private final Plane belowPlane;
|
private final Plane belowPlane;
|
||||||
private final Membership bound1;
|
private final Membership bound1;
|
||||||
private final Membership bound2;
|
private final Membership bound2;
|
||||||
private final Vector thePoint;
|
private final double thePointX;
|
||||||
|
private final double thePointY;
|
||||||
|
private final double thePointZ;
|
||||||
|
|
||||||
public int crossingCount = 0;
|
public int crossingCount = 0;
|
||||||
|
|
||||||
public LinearCrossingEdgeIterator(final Plane plane, final Plane abovePlane, final Plane belowPlane, final Vector thePoint) {
|
public LinearCrossingEdgeIterator(final Plane plane, final Plane abovePlane, final Plane belowPlane, final double thePointX, final double thePointY, final double thePointZ) {
|
||||||
this.plane = plane;
|
this.plane = plane;
|
||||||
this.abovePlane = abovePlane;
|
this.abovePlane = abovePlane;
|
||||||
this.belowPlane = belowPlane;
|
this.belowPlane = belowPlane;
|
||||||
this.bound1 = new SidedPlane(thePoint, plane, testPoint);
|
this.bound1 = new SidedPlane(thePointX, thePointY, thePointZ, plane, testPoint);
|
||||||
this.bound2 = new SidedPlane(testPoint, plane, thePoint);
|
this.bound2 = new SidedPlane(testPoint, plane, thePointX, thePointY, thePointZ);
|
||||||
this.thePoint = thePoint;
|
this.thePointX = thePointX;
|
||||||
|
this.thePointY = thePointY;
|
||||||
|
this.thePointZ = thePointZ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean matches(final Edge edge) {
|
public boolean matches(final Edge edge) {
|
||||||
// Early exit if the point is on the edge.
|
// Early exit if the point is on the edge.
|
||||||
if (thePoint != null && edge.plane.evaluateIsZero(thePoint) && edge.startPlane.isWithin(thePoint) && edge.endPlane.isWithin(thePoint)) {
|
if (edge.plane.evaluateIsZero(thePointX, thePointY, thePointZ) && edge.startPlane.isWithin(thePointX, thePointY, thePointZ) && edge.endPlane.isWithin(thePointX, thePointY, thePointZ)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
final GeoPoint[] crossingPoints = plane.findCrossings(planetModel, edge.plane, bound1, bound2, edge.startPlane, edge.endPlane);
|
final GeoPoint[] crossingPoints = plane.findCrossings(planetModel, edge.plane, bound1, bound2, edge.startPlane, edge.endPlane);
|
||||||
|
@ -864,7 +863,9 @@ class GeoComplexPolygon extends GeoBasePolygon {
|
||||||
private final Plane testPointAbovePlane;
|
private final Plane testPointAbovePlane;
|
||||||
private final Plane testPointBelowPlane;
|
private final Plane testPointBelowPlane;
|
||||||
private final Plane travelPlane;
|
private final Plane travelPlane;
|
||||||
private final Vector thePoint;
|
private final double thePointX;
|
||||||
|
private final double thePointY;
|
||||||
|
private final double thePointZ;
|
||||||
|
|
||||||
private final GeoPoint intersectionPoint;
|
private final GeoPoint intersectionPoint;
|
||||||
|
|
||||||
|
@ -888,12 +889,14 @@ class GeoComplexPolygon extends GeoBasePolygon {
|
||||||
public int crossingCount = 0;
|
public int crossingCount = 0;
|
||||||
|
|
||||||
public DualCrossingEdgeIterator(final Plane testPointPlane, final Plane testPointAbovePlane, final Plane testPointBelowPlane,
|
public DualCrossingEdgeIterator(final Plane testPointPlane, final Plane testPointAbovePlane, final Plane testPointBelowPlane,
|
||||||
final Plane travelPlane, final Vector thePoint, final GeoPoint intersectionPoint) {
|
final Plane travelPlane, final double thePointX, final double thePointY, final double thePointZ, final GeoPoint intersectionPoint) {
|
||||||
this.testPointPlane = testPointPlane;
|
this.testPointPlane = testPointPlane;
|
||||||
this.testPointAbovePlane = testPointAbovePlane;
|
this.testPointAbovePlane = testPointAbovePlane;
|
||||||
this.testPointBelowPlane = testPointBelowPlane;
|
this.testPointBelowPlane = testPointBelowPlane;
|
||||||
this.travelPlane = travelPlane;
|
this.travelPlane = travelPlane;
|
||||||
this.thePoint = thePoint;
|
this.thePointX = thePointX;
|
||||||
|
this.thePointY = thePointY;
|
||||||
|
this.thePointZ = thePointZ;
|
||||||
this.intersectionPoint = intersectionPoint;
|
this.intersectionPoint = intersectionPoint;
|
||||||
|
|
||||||
//System.err.println("Intersection point = "+intersectionPoint);
|
//System.err.println("Intersection point = "+intersectionPoint);
|
||||||
|
@ -902,12 +905,12 @@ class GeoComplexPolygon extends GeoBasePolygon {
|
||||||
assert testPointPlane.evaluateIsZero(intersectionPoint) : "intersection point must be on test point plane";
|
assert testPointPlane.evaluateIsZero(intersectionPoint) : "intersection point must be on test point plane";
|
||||||
|
|
||||||
assert !testPoint.isNumericallyIdentical(intersectionPoint) : "test point is the same as intersection point";
|
assert !testPoint.isNumericallyIdentical(intersectionPoint) : "test point is the same as intersection point";
|
||||||
assert !thePoint.isNumericallyIdentical(intersectionPoint) : "check point is same is intersection point";
|
assert !intersectionPoint.isNumericallyIdentical(thePointX, thePointY, thePointZ) : "check point is same is intersection point";
|
||||||
|
|
||||||
this.testPointCutoffPlane = new SidedPlane(intersectionPoint, testPointPlane, testPoint);
|
this.testPointCutoffPlane = new SidedPlane(intersectionPoint, testPointPlane, testPoint);
|
||||||
this.checkPointCutoffPlane = new SidedPlane(intersectionPoint, travelPlane, thePoint);
|
this.checkPointCutoffPlane = new SidedPlane(intersectionPoint, travelPlane, thePointX, thePointY, thePointZ);
|
||||||
this.testPointOtherCutoffPlane = new SidedPlane(testPoint, testPointPlane, intersectionPoint);
|
this.testPointOtherCutoffPlane = new SidedPlane(testPoint, testPointPlane, intersectionPoint);
|
||||||
this.checkPointOtherCutoffPlane = new SidedPlane(thePoint, travelPlane, intersectionPoint);
|
this.checkPointOtherCutoffPlane = new SidedPlane(thePointX, thePointY, thePointZ, travelPlane, intersectionPoint);
|
||||||
|
|
||||||
// Sanity check
|
// Sanity check
|
||||||
assert testPointCutoffPlane.isWithin(intersectionPoint) : "intersection must be within testPointCutoffPlane";
|
assert testPointCutoffPlane.isWithin(intersectionPoint) : "intersection must be within testPointCutoffPlane";
|
||||||
|
@ -922,7 +925,7 @@ class GeoComplexPolygon extends GeoBasePolygon {
|
||||||
// Convert travel plane to a sided plane
|
// Convert travel plane to a sided plane
|
||||||
final Membership intersectionBound1 = new SidedPlane(testPoint, travelPlane, travelPlane.D);
|
final Membership intersectionBound1 = new SidedPlane(testPoint, travelPlane, travelPlane.D);
|
||||||
// Convert testPoint plane to a sided plane
|
// Convert testPoint plane to a sided plane
|
||||||
final Membership intersectionBound2 = new SidedPlane(thePoint, testPointPlane, testPointPlane.D);
|
final Membership intersectionBound2 = new SidedPlane(thePointX, thePointY, thePointZ, testPointPlane, testPointPlane.D);
|
||||||
|
|
||||||
assert intersectionBound1.isWithin(intersectionPoint) : "intersection must be within intersectionBound1";
|
assert intersectionBound1.isWithin(intersectionPoint) : "intersection must be within intersectionBound1";
|
||||||
assert intersectionBound2.isWithin(intersectionPoint) : "intersection must be within intersectionBound2";
|
assert intersectionBound2.isWithin(intersectionPoint) : "intersection must be within intersectionBound2";
|
||||||
|
@ -966,7 +969,7 @@ class GeoComplexPolygon extends GeoBasePolygon {
|
||||||
testPointOutsidePlane = testPointBelowPlane;
|
testPointOutsidePlane = testPointBelowPlane;
|
||||||
}
|
}
|
||||||
|
|
||||||
insideTravelCutoffPlane = new SidedPlane(thePoint, testPointInsidePlane, testPointInsidePlane.D);
|
insideTravelCutoffPlane = new SidedPlane(thePointX, thePointY, thePointZ, testPointInsidePlane, testPointInsidePlane.D);
|
||||||
insideTestPointCutoffPlane = new SidedPlane(testPoint, travelInsidePlane, travelInsidePlane.D);
|
insideTestPointCutoffPlane = new SidedPlane(testPoint, travelInsidePlane, travelInsidePlane.D);
|
||||||
computedInsideOutside = true;
|
computedInsideOutside = true;
|
||||||
}
|
}
|
||||||
|
@ -980,7 +983,7 @@ class GeoComplexPolygon extends GeoBasePolygon {
|
||||||
public boolean matches(final Edge edge) {
|
public boolean matches(final Edge edge) {
|
||||||
//System.err.println("Processing edge "+edge+", startpoint="+edge.startPoint+" endpoint="+edge.endPoint);
|
//System.err.println("Processing edge "+edge+", startpoint="+edge.startPoint+" endpoint="+edge.endPoint);
|
||||||
// Early exit if the point is on the edge.
|
// Early exit if the point is on the edge.
|
||||||
if (thePoint != null && edge.plane.evaluateIsZero(thePoint) && edge.startPlane.isWithin(thePoint) && edge.endPlane.isWithin(thePoint)) {
|
if (edge.plane.evaluateIsZero(thePointX, thePointY, thePointZ) && edge.startPlane.isWithin(thePointX, thePointY, thePointZ) && edge.endPlane.isWithin(thePointX, thePointY, thePointZ)) {
|
||||||
//System.err.println(" Check point is on edge: isWithin = true");
|
//System.err.println(" Check point is on edge: isWithin = true");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,6 +49,19 @@ public class Plane extends Vector {
|
||||||
this.D = D;
|
this.D = D;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a plane through two points and origin.
|
||||||
|
*
|
||||||
|
* @param A is the first point (origin based).
|
||||||
|
* @param BX is the second point X (origin based).
|
||||||
|
* @param BY is the second point Y (origin based).
|
||||||
|
* @param BZ is the second point Z (origin based).
|
||||||
|
*/
|
||||||
|
public Plane(final Vector A, final double BX, final double BY, final double BZ) {
|
||||||
|
super(A, BX, BY, BZ);
|
||||||
|
D = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a plane through two points and origin.
|
* Construct a plane through two points and origin.
|
||||||
*
|
*
|
||||||
|
|
|
@ -36,6 +36,23 @@ public class SidedPlane extends Plane implements Membership {
|
||||||
this.sigNum = -sidedPlane.sigNum;
|
this.sigNum = -sidedPlane.sigNum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a sided plane from a pair of vectors describing points, and including
|
||||||
|
* origin, plus a point p which describes the side.
|
||||||
|
*
|
||||||
|
* @param pX point X to evaluate
|
||||||
|
* @param pY point Y to evaluate
|
||||||
|
* @param pZ point Z to evaluate
|
||||||
|
* @param A is the first in-plane point
|
||||||
|
* @param B is the second in-plane point
|
||||||
|
*/
|
||||||
|
public SidedPlane(final double pX, final double pY, final double pZ, final Vector A, final Vector B) {
|
||||||
|
super(A, B);
|
||||||
|
sigNum = Math.signum(evaluate(pX, pY, pZ));
|
||||||
|
if (sigNum == 0.0)
|
||||||
|
throw new IllegalArgumentException("Cannot determine sidedness because check point is on plane.");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a sided plane from a pair of vectors describing points, and including
|
* Construct a sided plane from a pair of vectors describing points, and including
|
||||||
* origin, plus a point p which describes the side.
|
* origin, plus a point p which describes the side.
|
||||||
|
@ -51,6 +68,23 @@ public class SidedPlane extends Plane implements Membership {
|
||||||
throw new IllegalArgumentException("Cannot determine sidedness because check point is on plane.");
|
throw new IllegalArgumentException("Cannot determine sidedness because check point is on plane.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a sided plane from a pair of vectors describing points, and including
|
||||||
|
* origin, plus a point p which describes the side.
|
||||||
|
*
|
||||||
|
* @param p point to evaluate
|
||||||
|
* @param A is the first in-plane point
|
||||||
|
* @param BX is the X value of the second in-plane point
|
||||||
|
* @param BY is the Y value of the second in-plane point
|
||||||
|
* @param BZ is the Z value of the second in-plane point
|
||||||
|
*/
|
||||||
|
public SidedPlane(final Vector p, final Vector A, final double BX, final double BY, final double BZ) {
|
||||||
|
super(A, BX, BY, BZ);
|
||||||
|
sigNum = Math.signum(evaluate(p));
|
||||||
|
if (sigNum == 0.0)
|
||||||
|
throw new IllegalArgumentException("Cannot determine sidedness because check point is on plane.");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a sided plane from a pair of vectors describing points, and including
|
* Construct a sided plane from a pair of vectors describing points, and including
|
||||||
* origin, plus a point p which describes the side.
|
* origin, plus a point p which describes the side.
|
||||||
|
|
|
@ -56,6 +56,34 @@ public class Vector {
|
||||||
this.z = z;
|
this.z = z;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a vector that is perpendicular to
|
||||||
|
* two other (non-zero) vectors. If the vectors are parallel,
|
||||||
|
* IllegalArgumentException will be thrown.
|
||||||
|
* Produces a normalized final vector.
|
||||||
|
*
|
||||||
|
* @param A is the first vector
|
||||||
|
* @param BX is the X value of the second
|
||||||
|
* @param BY is the Y value of the second
|
||||||
|
* @param BZ is the Z value of the second
|
||||||
|
*/
|
||||||
|
public Vector(final Vector A, final double BX, final double BY, final double BZ) {
|
||||||
|
// x = u2v3 - u3v2
|
||||||
|
// y = u3v1 - u1v3
|
||||||
|
// z = u1v2 - u2v1
|
||||||
|
final double thisX = A.y * BZ - A.z * BY;
|
||||||
|
final double thisY = A.z * BX - A.x * BZ;
|
||||||
|
final double thisZ = A.x * BY - A.y * BX;
|
||||||
|
final double magnitude = magnitude(thisX, thisY, thisZ);
|
||||||
|
if (Math.abs(magnitude) < MINIMUM_RESOLUTION) {
|
||||||
|
throw new IllegalArgumentException("Degenerate/parallel vector constructed");
|
||||||
|
}
|
||||||
|
final double inverseMagnitude = 1.0 / magnitude;
|
||||||
|
this.x = thisX * inverseMagnitude;
|
||||||
|
this.y = thisY * inverseMagnitude;
|
||||||
|
this.z = thisZ * inverseMagnitude;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a vector that is perpendicular to
|
* Construct a vector that is perpendicular to
|
||||||
* two other (non-zero) vectors. If the vectors are parallel,
|
* two other (non-zero) vectors. If the vectors are parallel,
|
||||||
|
@ -328,6 +356,20 @@ public class Vector {
|
||||||
return magnitude(x,y,z);
|
return magnitude(x,y,z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute whether two vectors are numerically identical.
|
||||||
|
* @param otherX is the other vector X.
|
||||||
|
* @param otherY is the other vector Y.
|
||||||
|
* @param otherZ is the other vector Z.
|
||||||
|
* @return true if they are numerically identical.
|
||||||
|
*/
|
||||||
|
public boolean isNumericallyIdentical(final double otherX, final double otherY, final double otherZ) {
|
||||||
|
final double thisX = y * otherZ - z * otherY;
|
||||||
|
final double thisY = z * otherX - x * otherZ;
|
||||||
|
final double thisZ = x * otherY - y * otherX;
|
||||||
|
return thisX * thisX + thisY * thisY + thisZ * thisZ < MINIMUM_RESOLUTION_SQUARED;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compute whether two vectors are numerically identical.
|
* Compute whether two vectors are numerically identical.
|
||||||
* @param other is the other vector.
|
* @param other is the other vector.
|
||||||
|
|
Loading…
Reference in New Issue