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,
|
public static SidedPlane constructNormalizedThreePointSidedPlane(final Vector insidePoint,
|
||||||
final Vector point1, final Vector point2, final Vector point3) {
|
final Vector point1, final Vector point2, final Vector point3) {
|
||||||
try {
|
SidedPlane rval = null;
|
||||||
final Vector planeNormal = new Vector(
|
|
||||||
new Vector(point1.x - point2.x, point1.y - point2.y, point1.z - point2.z),
|
if (rval == null) {
|
||||||
new Vector(point2.x - point3.x, point2.y - point3.y, point2.z - point3.z));
|
try {
|
||||||
return new SidedPlane(insidePoint, planeNormal, -planeNormal.dotProduct(point2));
|
final Vector planeNormal = new Vector(
|
||||||
} catch (IllegalArgumentException e) {
|
point1.x - point2.x, point1.y - point2.y, point1.z - point2.z,
|
||||||
return null;
|
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
|
@Override
|
||||||
|
|
|
@ -72,6 +72,24 @@ public class Vector {
|
||||||
* @param BZ is the Z 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) {
|
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'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.
|
// 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:
|
// 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
|
// Gram-Schmidt process: https://en.wikipedia.org/wiki/Gram%E2%80%93Schmidt_process
|
||||||
|
|
||||||
// Compute the naive perpendicular
|
// Compute the naive perpendicular
|
||||||
final double thisX = A.y * BZ - A.z * BY;
|
final double thisX = AY * BZ - AZ * BY;
|
||||||
final double thisY = A.z * BX - A.x * BZ;
|
final double thisY = AZ * BX - AX * BZ;
|
||||||
final double thisZ = A.x * BY - A.y * BX;
|
final double thisZ = AX * BY - AY * BX;
|
||||||
|
|
||||||
final double magnitude = magnitude(thisX, thisY, thisZ);
|
final double magnitude = magnitude(thisX, thisY, thisZ);
|
||||||
if (magnitude < MINIMUM_RESOLUTION) {
|
if (magnitude < MINIMUM_RESOLUTION) {
|
||||||
|
@ -103,7 +121,7 @@ public class Vector {
|
||||||
// we need to adjust
|
// we need to adjust
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while (true) {
|
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;
|
final double currentDotProdB = BX * normalizeX + BY * normalizeY + BZ * normalizeZ;
|
||||||
if (Math.abs(currentDotProdA) < MINIMUM_RESOLUTION && Math.abs(currentDotProdB) < MINIMUM_RESOLUTION) {
|
if (Math.abs(currentDotProdA) < MINIMUM_RESOLUTION && Math.abs(currentDotProdB) < MINIMUM_RESOLUTION) {
|
||||||
break;
|
break;
|
||||||
|
@ -114,9 +132,9 @@ public class Vector {
|
||||||
final double currentVectorZ;
|
final double currentVectorZ;
|
||||||
final double currentDotProd;
|
final double currentDotProd;
|
||||||
if (Math.abs(currentDotProdA) > Math.abs(currentDotProdB)) {
|
if (Math.abs(currentDotProdA) > Math.abs(currentDotProdB)) {
|
||||||
currentVectorX = A.x;
|
currentVectorX = AX;
|
||||||
currentVectorY = A.y;
|
currentVectorY = AY;
|
||||||
currentVectorZ = A.z;
|
currentVectorZ = AZ;
|
||||||
currentDotProd = currentDotProdA;
|
currentDotProd = currentDotProdA;
|
||||||
} else {
|
} else {
|
||||||
currentVectorX = BX;
|
currentVectorX = BX;
|
||||||
|
|
|
@ -22,6 +22,7 @@ import java.util.List;
|
||||||
|
|
||||||
import com.carrotsearch.randomizedtesting.annotations.Repeat;
|
import com.carrotsearch.randomizedtesting.annotations.Repeat;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.junit.Ignore;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Random test for planes.
|
* 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
|
@Test
|
||||||
|
|
Loading…
Reference in New Issue