mirror of https://github.com/apache/lucene.git
LUCENE-8171: Refactor vector constructor to support later changes, and add an ignored test for a precision issue.
This commit is contained in:
parent
277097cd24
commit
4f351fd21b
|
@ -177,14 +177,39 @@ public class SidedPlane extends Plane implements Membership {
|
|||
*/
|
||||
public static SidedPlane constructNormalizedThreePointSidedPlane(final Vector insidePoint,
|
||||
final Vector point1, final Vector point2, final Vector point3) {
|
||||
try {
|
||||
final Vector planeNormal = new Vector(
|
||||
new Vector(point1.x - point2.x, point1.y - point2.y, point1.z - point2.z),
|
||||
new Vector(point2.x - point3.x, point2.y - point3.y, point2.z - point3.z));
|
||||
return new SidedPlane(insidePoint, planeNormal, -planeNormal.dotProduct(point2));
|
||||
} catch (IllegalArgumentException e) {
|
||||
return null;
|
||||
SidedPlane rval = null;
|
||||
|
||||
if (rval == null) {
|
||||
try {
|
||||
final Vector planeNormal = new Vector(
|
||||
point1.x - point2.x, point1.y - point2.y, point1.z - point2.z,
|
||||
point2.x - point3.x, point2.y - point3.y, point2.z - point3.z);
|
||||
rval = new SidedPlane(insidePoint, planeNormal, -planeNormal.dotProduct(point2));
|
||||
} catch (IllegalArgumentException e) {
|
||||
}
|
||||
}
|
||||
|
||||
if (rval == null) {
|
||||
try {
|
||||
final Vector planeNormal = new Vector(
|
||||
point1.x - point3.x, point1.y - point3.y, point1.z - point3.z,
|
||||
point3.x - point2.x, point3.y - point2.y, point3.z - point2.z);
|
||||
rval = new SidedPlane(insidePoint, planeNormal, -planeNormal.dotProduct(point3));
|
||||
} catch (IllegalArgumentException e) {
|
||||
}
|
||||
}
|
||||
|
||||
if (rval == null) {
|
||||
try {
|
||||
final Vector planeNormal = new Vector(
|
||||
point3.x - point1.x, point3.y - point1.y, point3.z - point1.z,
|
||||
point1.x - point2.x, point1.y - point2.y, point1.z - point2.z);
|
||||
rval = new SidedPlane(insidePoint, planeNormal, -planeNormal.dotProduct(point1));
|
||||
} catch (IllegalArgumentException e) {
|
||||
}
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -72,6 +72,24 @@ public class Vector {
|
|||
* @param BZ is the Z value of the second
|
||||
*/
|
||||
public Vector(final Vector A, final double BX, final double BY, final double BZ) {
|
||||
// We're really looking at two vectors and computing a perpendicular one from that.
|
||||
this(A.x, A.y, A.z, BX, BY, BZ);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 AX is the X value of the first
|
||||
* @param AY is the Y value of the first
|
||||
* @param AZ is the Z value of the first
|
||||
* @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 double AX, final double AY, final double AZ, final double BX, final double BY, final double BZ) {
|
||||
// We're really looking at two vectors and computing a perpendicular one from that.
|
||||
// We can think of this as having three points -- the origin, and two points that aren't the origin.
|
||||
// Normally, we can compute the perpendicular vector this way:
|
||||
|
@ -83,9 +101,9 @@ public class Vector {
|
|||
// Gram-Schmidt process: https://en.wikipedia.org/wiki/Gram%E2%80%93Schmidt_process
|
||||
|
||||
// Compute the naive perpendicular
|
||||
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 thisX = AY * BZ - AZ * BY;
|
||||
final double thisY = AZ * BX - AX * BZ;
|
||||
final double thisZ = AX * BY - AY * BX;
|
||||
|
||||
final double magnitude = magnitude(thisX, thisY, thisZ);
|
||||
if (magnitude < MINIMUM_RESOLUTION) {
|
||||
|
@ -103,7 +121,7 @@ public class Vector {
|
|||
// we need to adjust
|
||||
int i = 0;
|
||||
while (true) {
|
||||
final double currentDotProdA = A.x * normalizeX + A.y * normalizeY + A.z * normalizeZ;
|
||||
final double currentDotProdA = AX * normalizeX + AY * normalizeY + AZ * normalizeZ;
|
||||
final double currentDotProdB = BX * normalizeX + BY * normalizeY + BZ * normalizeZ;
|
||||
if (Math.abs(currentDotProdA) < MINIMUM_RESOLUTION && Math.abs(currentDotProdB) < MINIMUM_RESOLUTION) {
|
||||
break;
|
||||
|
@ -114,9 +132,9 @@ public class Vector {
|
|||
final double currentVectorZ;
|
||||
final double currentDotProd;
|
||||
if (Math.abs(currentDotProdA) > Math.abs(currentDotProdB)) {
|
||||
currentVectorX = A.x;
|
||||
currentVectorY = A.y;
|
||||
currentVectorZ = A.z;
|
||||
currentVectorX = AX;
|
||||
currentVectorY = AY;
|
||||
currentVectorZ = AZ;
|
||||
currentDotProd = currentDotProdA;
|
||||
} else {
|
||||
currentVectorX = BX;
|
||||
|
|
|
@ -22,6 +22,7 @@ import java.util.List;
|
|||
|
||||
import com.carrotsearch.randomizedtesting.annotations.Repeat;
|
||||
import org.junit.Test;
|
||||
import org.junit.Ignore;
|
||||
|
||||
/**
|
||||
* Random test for planes.
|
||||
|
@ -50,6 +51,33 @@ public class RandomPlaneTest extends RandomGeo3dShapeGenerator {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Ignore
|
||||
@Test
|
||||
@Repeat(iterations = 10)
|
||||
public void testPlaneThreePointsAccuracy() {
|
||||
PlanetModel planetModel = randomPlanetModel();
|
||||
for (int i= 0; i < 1000; i++) {
|
||||
GeoPoint point1 = randomGeoPoint(planetModel);
|
||||
double dist = random().nextDouble() * Math.PI - Vector.MINIMUM_ANGULAR_RESOLUTION;
|
||||
double bearing = random().nextDouble() * 2 * Math.PI;
|
||||
GeoPoint point2 = planetModel.surfacePointOnBearing(point1, dist, bearing );
|
||||
dist = random().nextDouble() * Vector.MINIMUM_ANGULAR_RESOLUTION + Vector.MINIMUM_ANGULAR_RESOLUTION;
|
||||
bearing = random().nextDouble() * 2 * Math.PI;
|
||||
GeoPoint point3 = planetModel.surfacePointOnBearing(point1, dist, bearing );
|
||||
GeoPoint check = randomGeoPoint(planetModel);
|
||||
SidedPlane plane = SidedPlane.constructNormalizedThreePointSidedPlane(check, point1, point2, point3);
|
||||
String msg = planetModel + " point 1: " + point1 + ", point 2: " + point2 + ", point 3: " + point3 + " , check: " + check;
|
||||
if (plane == null) {
|
||||
fail(msg);
|
||||
}
|
||||
assertTrue(plane.evaluate(check) + " " + msg, plane.isWithin(check));
|
||||
assertTrue(plane.evaluate(point1) + " " +msg, plane.isWithin(point3));
|
||||
assertTrue(plane.evaluate(point2) + " " +msg, plane.isWithin(point2));
|
||||
assertTrue(plane.evaluate(point3) + " " +msg, plane.isWithin(point1));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
|
|
Loading…
Reference in New Issue