You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by kw...@apache.org on 2016/04/19 16:20:35 UTC
lucene-solr:master: LUCENE-7212: Structural changes necessary to
support distance-limited bounds.
Repository: lucene-solr
Updated Branches:
refs/heads/master 02f1dacc3 -> 234229081
LUCENE-7212: Structural changes necessary to support distance-limited bounds.
Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/23422908
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/23422908
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/23422908
Branch: refs/heads/master
Commit: 23422908165f62581c271524955af2ab0e6e069f
Parents: 02f1dac
Author: Karl Wright <Da...@gmail.com>
Authored: Tue Apr 19 10:20:00 2016 -0400
Committer: Karl Wright <Da...@gmail.com>
Committed: Tue Apr 19 10:20:00 2016 -0400
----------------------------------------------------------------------
.../org/apache/lucene/spatial3d/Geo3DUtil.java | 1 +
.../lucene/spatial3d/geom/ArcDistance.java | 15 +++
.../lucene/spatial3d/geom/DistanceStyle.java | 28 +++++
.../spatial3d/geom/GeoBaseDistanceShape.java | 12 ++
.../spatial3d/geom/GeoDegeneratePoint.java | 6 +
.../lucene/spatial3d/geom/GeoDistance.java | 1 +
.../lucene/spatial3d/geom/GeoDistanceShape.java | 12 ++
.../spatial3d/geom/GeoStandardCircle.java | 6 +
.../lucene/spatial3d/geom/GeoStandardPath.java | 6 +
.../lucene/spatial3d/geom/LinearDistance.java | 15 +++
.../spatial3d/geom/LinearSquaredDistance.java | 15 +++
.../lucene/spatial3d/geom/NormalDistance.java | 15 +++
.../spatial3d/geom/NormalSquaredDistance.java | 15 +++
.../org/apache/lucene/spatial3d/geom/Plane.java | 114 +++++++++++++++++++
.../apache/lucene/spatial3d/geom/PlaneTest.java | 20 ++++
15 files changed, 281 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/23422908/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/Geo3DUtil.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/Geo3DUtil.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/Geo3DUtil.java
index f91a6f6..bfda66f 100644
--- a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/Geo3DUtil.java
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/Geo3DUtil.java
@@ -64,4 +64,5 @@ class Geo3DUtil {
return Math.nextDown((x+1) * DECODE);
}
}
+
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/23422908/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/ArcDistance.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/ArcDistance.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/ArcDistance.java
index bb60be0..25b9c7d 100644
--- a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/ArcDistance.java
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/ArcDistance.java
@@ -51,6 +51,21 @@ public class ArcDistance implements DistanceStyle {
return plane.arcDistance(planetModel, x,y,z, bounds);
}
+ @Override
+ public GeoPoint[] findDistancePoints(final PlanetModel planetModel, final double distanceValue, final GeoPoint startPoint, final Plane plane, final Membership... bounds) {
+ return plane.findArcDistancePoints(planetModel, distanceValue, startPoint, bounds);
+ }
+
+ @Override
+ public double findMinimumArcDistance(final PlanetModel planetModel, final double distanceValue) {
+ return distanceValue;
+ }
+
+ @Override
+ public double findMaximumArcDistance(final PlanetModel planetModel, final double distanceValue) {
+ return distanceValue;
+ }
+
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/23422908/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/DistanceStyle.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/DistanceStyle.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/DistanceStyle.java
index 8c8658d..3657fe9 100644
--- a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/DistanceStyle.java
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/DistanceStyle.java
@@ -78,6 +78,34 @@ public interface DistanceStyle {
*/
public double computeDistance(final PlanetModel planetModel, final Plane plane, final double x, final double y, final double z, final Membership... bounds);
+ // The following methods are used to go from a distance value back to something
+ // that can be used to construct a constrained shape.
+
+ /** Find a GeoPoint, at a specified distance from a starting point, within the
+ * specified bounds. The GeoPoint must be in the specified plane.
+ * @param planetModel is the planet model.
+ * @param distanceValue is the distance to set the new point at, measured from point1 and on the way to point2.
+ * @param startPoint is the starting point.
+ * @param plane is the plane that the point must be in.
+ * @param bounds are the constraints on where the point can be found.
+ * @return zero, one, or two points at the proper distance from startPoint.
+ */
+ public GeoPoint[] findDistancePoints(final PlanetModel planetModel, final double distanceValue, final GeoPoint startPoint, final Plane plane, final Membership... bounds);
+
+ /** Given a distance metric, find the minimum arc distance represented by that distance metric.
+ * @param planetModel is the planet model.
+ * @param distanceValue is the distance metric.
+ * @return the minimum arc distance that that distance value can represent given the planet model.
+ */
+ public double findMinimumArcDistance(final PlanetModel planetModel, final double distanceValue);
+
+ /** Given a distance metric, find the maximum arc distance represented by the distance metric.
+ * @param planetModel is the planet model.
+ * @param distanceValue is the distance metric.
+ * @return the maximum arc distance that that distance value can represent given the planet model.
+ */
+ public double findMaximumArcDistance(final PlanetModel planetModel, final double distanceValue);
+
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/23422908/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoBaseDistanceShape.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoBaseDistanceShape.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoBaseDistanceShape.java
index 39dcf96..ec9b6b7 100644
--- a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoBaseDistanceShape.java
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoBaseDistanceShape.java
@@ -52,5 +52,17 @@ public abstract class GeoBaseDistanceShape extends GeoBaseMembershipShape implem
/** Called by a {@code computeDistance} method if X/Y/Z is not within this shape. */
protected abstract double distance(final DistanceStyle distanceStyle, final double x, final double y, final double z);
+ @Override
+ public void getDistanceBounds(final Bounds bounds, final DistanceStyle distanceStyle, final double distanceValue) {
+ if (distanceValue == Double.MAX_VALUE) {
+ getBounds(bounds);
+ return;
+ }
+ distanceBounds(bounds, distanceStyle, distanceValue);
+ }
+
+ /** Called by a {@code getDistanceBounds} method if distanceValue is not Double.MAX_VALUE. */
+ protected abstract void distanceBounds(final Bounds bounds, final DistanceStyle distanceStyle, final double distanceValue);
+
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/23422908/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoDegeneratePoint.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoDegeneratePoint.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoDegeneratePoint.java
index aa4732d..9328b4b 100644
--- a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoDegeneratePoint.java
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoDegeneratePoint.java
@@ -131,5 +131,11 @@ class GeoDegeneratePoint extends GeoPoint implements GeoBBox, GeoCircle {
return 0.0;
return Double.MAX_VALUE;
}
+
+ @Override
+ public void getDistanceBounds(final Bounds bounds, final DistanceStyle distanceStyle, final double distanceValue) {
+ getBounds(bounds);
+ }
+
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/23422908/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoDistance.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoDistance.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoDistance.java
index d41dd51..cf8fa23 100755
--- a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoDistance.java
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoDistance.java
@@ -56,4 +56,5 @@ public interface GeoDistance extends Membership {
*/
public double computeDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z);
+
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/23422908/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoDistanceShape.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoDistanceShape.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoDistanceShape.java
index e7b0348..ebd433f 100755
--- a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoDistanceShape.java
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoDistanceShape.java
@@ -24,4 +24,16 @@ package org.apache.lucene.spatial3d.geom;
*/
public interface GeoDistanceShape extends GeoMembershipShape, GeoDistance {
+ /**
+ * Compute a bound based on a provided distance measure.
+ * This method takes an input distance and distance metric and provides bounds on the
+ * shape if reduced to match that distance. The method is allowed to return
+ * bounds that are larger than the distance would indicate, but never smaller.
+ * @param bounds is the bounds object to update.
+ * @param distanceStyle describes the type of distance metric provided.
+ * @param distanceValue is the distance metric to use. It is presumed that the distance metric
+ * was produced with the same distance style as is provided to this method.
+ */
+ public void getDistanceBounds(final Bounds bounds, final DistanceStyle distanceStyle, final double distanceValue);
+
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/23422908/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoStandardCircle.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoStandardCircle.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoStandardCircle.java
index 1bc25be..06bef00 100755
--- a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoStandardCircle.java
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoStandardCircle.java
@@ -107,6 +107,12 @@ class GeoStandardCircle extends GeoBaseCircle {
}
@Override
+ protected void distanceBounds(final Bounds bounds, final DistanceStyle distanceStyle, final double distanceValue) {
+ // TBD: Compute actual bounds based on distance
+ getBounds(bounds);
+ }
+
+ @Override
protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
return distanceStyle.computeDistance(planetModel, circlePlane, x, y, z);
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/23422908/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoStandardPath.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoStandardPath.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoStandardPath.java
index 1546439..312b79e 100755
--- a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoStandardPath.java
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoStandardPath.java
@@ -220,6 +220,12 @@ class GeoStandardPath extends GeoBasePath {
}
@Override
+ protected void distanceBounds(final Bounds bounds, final DistanceStyle distanceStyle, final double distanceValue) {
+ // TBD: Compute actual bounds based on distance
+ getBounds(bounds);
+ }
+
+ @Override
protected double outsideDistance(final DistanceStyle distanceStyle, final double x, final double y, final double z) {
double minDistance = Double.MAX_VALUE;
for (final SegmentEndpoint endpoint : endPoints) {
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/23422908/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/LinearDistance.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/LinearDistance.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/LinearDistance.java
index 0c89a16..f301f49 100644
--- a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/LinearDistance.java
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/LinearDistance.java
@@ -51,6 +51,21 @@ public class LinearDistance implements DistanceStyle {
return plane.linearDistance(planetModel, x,y,z, bounds);
}
+ @Override
+ public GeoPoint[] findDistancePoints(final PlanetModel planetModel, final double distanceValue, final GeoPoint startPoint, final Plane plane, final Membership... bounds) {
+ throw new IllegalStateException("Reverse mapping not implemented for this distance metric");
+ }
+
+ @Override
+ public double findMinimumArcDistance(final PlanetModel planetModel, final double distanceValue) {
+ throw new IllegalStateException("Reverse mapping not implemented for this distance metric");
+ }
+
+ @Override
+ public double findMaximumArcDistance(final PlanetModel planetModel, final double distanceValue) {
+ throw new IllegalStateException("Reverse mapping not implemented for this distance metric");
+ }
+
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/23422908/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/LinearSquaredDistance.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/LinearSquaredDistance.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/LinearSquaredDistance.java
index 3fc37da..4b26f8e 100644
--- a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/LinearSquaredDistance.java
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/LinearSquaredDistance.java
@@ -51,6 +51,21 @@ public class LinearSquaredDistance implements DistanceStyle {
return plane.linearDistanceSquared(planetModel, x,y,z, bounds);
}
+ @Override
+ public GeoPoint[] findDistancePoints(final PlanetModel planetModel, final double distanceValue, final GeoPoint startPoint, final Plane plane, final Membership... bounds) {
+ throw new IllegalStateException("Reverse mapping not implemented for this distance metric");
+ }
+
+ @Override
+ public double findMinimumArcDistance(final PlanetModel planetModel, final double distanceValue) {
+ throw new IllegalStateException("Reverse mapping not implemented for this distance metric");
+ }
+
+ @Override
+ public double findMaximumArcDistance(final PlanetModel planetModel, final double distanceValue) {
+ throw new IllegalStateException("Reverse mapping not implemented for this distance metric");
+ }
+
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/23422908/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/NormalDistance.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/NormalDistance.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/NormalDistance.java
index 50b2c7f..64fd20b 100644
--- a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/NormalDistance.java
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/NormalDistance.java
@@ -51,6 +51,21 @@ public class NormalDistance implements DistanceStyle {
return plane.normalDistance(x,y,z, bounds);
}
+ @Override
+ public GeoPoint[] findDistancePoints(final PlanetModel planetModel, final double distanceValue, final GeoPoint startPoint, final Plane plane, final Membership... bounds) {
+ throw new IllegalStateException("Reverse mapping not implemented for this distance metric");
+ }
+
+ @Override
+ public double findMinimumArcDistance(final PlanetModel planetModel, final double distanceValue) {
+ throw new IllegalStateException("Reverse mapping not implemented for this distance metric");
+ }
+
+ @Override
+ public double findMaximumArcDistance(final PlanetModel planetModel, final double distanceValue) {
+ throw new IllegalStateException("Reverse mapping not implemented for this distance metric");
+ }
+
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/23422908/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/NormalSquaredDistance.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/NormalSquaredDistance.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/NormalSquaredDistance.java
index a355d09..428e042 100644
--- a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/NormalSquaredDistance.java
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/NormalSquaredDistance.java
@@ -51,6 +51,21 @@ public class NormalSquaredDistance implements DistanceStyle {
return plane.normalDistanceSquared(x,y,z, bounds);
}
+ @Override
+ public GeoPoint[] findDistancePoints(final PlanetModel planetModel, final double distanceValue, final GeoPoint startPoint, final Plane plane, final Membership... bounds) {
+ throw new IllegalStateException("Reverse mapping not implemented for this distance metric");
+ }
+
+ @Override
+ public double findMinimumArcDistance(final PlanetModel planetModel, final double distanceValue) {
+ throw new IllegalStateException("Reverse mapping not implemented for this distance metric");
+ }
+
+ @Override
+ public double findMaximumArcDistance(final PlanetModel planetModel, final double distanceValue) {
+ throw new IllegalStateException("Reverse mapping not implemented for this distance metric");
+ }
+
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/23422908/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/Plane.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/Plane.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/Plane.java
index ace7aa4..f0df49d 100755
--- a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/Plane.java
+++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/Plane.java
@@ -1558,6 +1558,120 @@ public class Plane extends Vector {
}
/**
+ * Locate a point that is within the specified bounds and on the specified plane, that has an arcDistance as
+ * specified from the startPoint.
+ * @param planetModel is the planet model.
+ * @param arcDistanceValue is the arc distance.
+ * @param startPoint is the starting point.
+ * @param bounds are the bounds.
+ * @return zero, one, or two points.
+ */
+ public GeoPoint[] findArcDistancePoints(final PlanetModel planetModel, final double arcDistanceValue, final GeoPoint startPoint, final Membership... bounds) {
+ if (Math.abs(D) >= MINIMUM_RESOLUTION) {
+ throw new IllegalStateException("Can't find arc distance using plane that doesn't go through origin");
+ }
+ if (!evaluateIsZero(startPoint)) {
+ throw new IllegalArgumentException("Start point is not on plane");
+ }
+ assert Math.abs(x*x + y*y + z*z - 1.0) < MINIMUM_RESOLUTION_SQUARED : "Plane needs to be normalized";
+
+ // The first step is to rotate coordinates for the point so that the plane lies on the x-y plane.
+ // To acheive this, there will need to be three rotations:
+ // (1) rotate the plane in x-y so that the y axis lies in it.
+ // (2) rotate the plane in x-z so that the plane lies on the x-y plane.
+ // (3) rotate in x-y so that the starting vector points to (1,0,0).
+
+ // This presumes a normalized plane!!
+ final double azimuthMagnitude = Math.sqrt(this.x * this.x + this.y * this.y);
+ final double cosPlaneAltitude = this.z;
+ final double sinPlaneAltitude = azimuthMagnitude;
+ final double cosPlaneAzimuth = this.x / azimuthMagnitude;
+ final double sinPlaneAzimuth = this.y / azimuthMagnitude;
+
+ assert Math.abs(sinPlaneAltitude * sinPlaneAltitude + cosPlaneAltitude * cosPlaneAltitude - 1.0) < MINIMUM_RESOLUTION : "Improper sin/cos of altitude: "+(sinPlaneAltitude * sinPlaneAltitude + cosPlaneAltitude * cosPlaneAltitude);
+ assert Math.abs(sinPlaneAzimuth * sinPlaneAzimuth + cosPlaneAzimuth * cosPlaneAzimuth - 1.0) < MINIMUM_RESOLUTION : "Improper sin/cos of azimuth: "+(sinPlaneAzimuth * sinPlaneAzimuth + cosPlaneAzimuth * cosPlaneAzimuth);
+
+ // Coordinate rotation formula:
+ // xT = xS cos T - yS sin T
+ // yT = xS sin T + yS cos T
+ // But we're rotating backwards, so use:
+ // sin (-T) = -sin (T)
+ // cos (-T) = cos (T)
+
+ // Now, rotate startpoint in x-y
+ final double x0 = startPoint.x;
+ final double y0 = startPoint.y;
+ final double z0 = startPoint.z;
+
+ final double x1 = x0 * cosPlaneAzimuth + y0 * sinPlaneAzimuth;
+ final double y1 = -x0 * sinPlaneAzimuth + y0 * cosPlaneAzimuth;
+ final double z1 = z0;
+
+ // Rotate now in x-z
+ final double x2 = x1 * cosPlaneAltitude - z1 * sinPlaneAltitude;
+ final double y2 = y1;
+ final double z2 = +x1 * sinPlaneAltitude + z1 * cosPlaneAltitude;
+
+ assert Math.abs(z2) < MINIMUM_RESOLUTION : "Rotation should have put startpoint on x-y plane, instead has value "+z2;
+
+ // Ok, we have the start point on the x-y plane. To apply the arc distance, we
+ // next need to convert to an angle (in radians).
+ final double startAngle = Math.atan2(y2, x2);
+
+ // To apply the arc distance, just add to startAngle.
+ final double point1Angle = startAngle + arcDistanceValue;
+ final double point2Angle = startAngle - arcDistanceValue;
+ // Convert each point to x-y
+ final double point1x2 = Math.cos(point1Angle);
+ final double point1y2 = Math.sin(point1Angle);
+ final double point1z2 = 0.0;
+
+ final double point2x2 = Math.cos(point2Angle);
+ final double point2y2 = Math.sin(point2Angle);
+ final double point2z2 = 0.0;
+
+ // Now, do the reverse rotations for both points
+ // Altitude...
+ final double point1x1 = point1x2 * cosPlaneAltitude + point1z2 * sinPlaneAltitude;
+ final double point1y1 = point1y2;
+ final double point1z1 = -point1x2 * sinPlaneAltitude + point1z2 * cosPlaneAltitude;
+
+ final double point2x1 = point2x2 * cosPlaneAltitude + point2z2 * sinPlaneAltitude;
+ final double point2y1 = point2y2;
+ final double point2z1 = -point2x2 * sinPlaneAltitude + point2z2 * cosPlaneAltitude;
+
+ // Azimuth...
+ final double point1x0 = point1x1 * cosPlaneAzimuth - point1y1 * sinPlaneAzimuth;
+ final double point1y0 = point1x1 * sinPlaneAzimuth + point1y1 * cosPlaneAzimuth;
+ final double point1z0 = point1z1;
+
+ final double point2x0 = point2x1 * cosPlaneAzimuth - point2y1 * sinPlaneAzimuth;
+ final double point2y0 = point2x1 * sinPlaneAzimuth + point2y1 * cosPlaneAzimuth;
+ final double point2z0 = point2z1;
+
+ final GeoPoint point1 = planetModel.createSurfacePoint(point1x0, point1y0, point1z0);
+ final GeoPoint point2 = planetModel.createSurfacePoint(point2x0, point2y0, point2z0);
+
+ // Figure out what to return
+ boolean isPoint1Inside = meetsAllBounds(point1, bounds);
+ boolean isPoint2Inside = meetsAllBounds(point2, bounds);
+
+ if (isPoint1Inside) {
+ if (isPoint2Inside) {
+ return new GeoPoint[]{point1, point2};
+ } else {
+ return new GeoPoint[]{point1};
+ }
+ } else {
+ if (isPoint2Inside) {
+ return new GeoPoint[]{point2};
+ } else {
+ return new GeoPoint[0];
+ }
+ }
+ }
+
+ /**
* Check if a vector meets the provided bounds.
* @param p is the vector.
* @param bounds are the bounds.
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/23422908/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/PlaneTest.java
----------------------------------------------------------------------
diff --git a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/PlaneTest.java b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/PlaneTest.java
index 91bd0c3..5f64bdf 100644
--- a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/PlaneTest.java
+++ b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/geom/PlaneTest.java
@@ -20,6 +20,7 @@ import org.junit.Test;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertEquals;
/**
* Test basic plane functionality.
@@ -60,5 +61,24 @@ public class PlaneTest {
assertTrue(p.evaluateIsZero(point));
}
}
+
+ @Test
+ public void testFindArcPoints() {
+ // Create two points
+ final GeoPoint p1 = new GeoPoint(PlanetModel.WGS84, 0.123, -0.456);
+ final GeoPoint p2 = new GeoPoint(PlanetModel.WGS84, -0.368, 0.888);
+ // Create a plane that links them.
+ final Plane plane = new Plane(p1, p2);
+ // Now, use that plane to find points that are a certain distance from the original
+ final GeoPoint[] newPoints = plane.findArcDistancePoints(PlanetModel.WGS84, 0.20, p1);
+ assertTrue(newPoints.length == 2);
+ assertTrue(plane.evaluateIsZero(newPoints[0]));
+ assertTrue(plane.evaluateIsZero(newPoints[1]));
+ assertTrue(PlanetModel.WGS84.pointOnSurface(newPoints[0]));
+ assertTrue(PlanetModel.WGS84.pointOnSurface(newPoints[1]));
+ assertEquals(0.20, p1.arcDistance(newPoints[0]), 1e-6);
+ assertEquals(0.20, p1.arcDistance(newPoints[1]), 1e-6);
+ }
+
}