mirror of https://github.com/apache/lucene.git
Fix nearestDistance for real this time
This commit is contained in:
parent
5d341e9d8c
commit
799421abba
|
@ -21,9 +21,9 @@ import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GeoShape representing a path across the surface of the globe, with a specified half-width. Path
|
* GeoShape representing a path across the surface of the globe, with a specified half-width. Path
|
||||||
|
@ -109,7 +109,7 @@ class GeoDegeneratePath extends GeoBasePath {
|
||||||
// Simple circle
|
// Simple circle
|
||||||
final GeoPoint point = points.get(0);
|
final GeoPoint point = points.get(0);
|
||||||
|
|
||||||
final SegmentEndpoint onlyEndpoint = new SegmentEndpoint(point);
|
final SegmentEndpoint onlyEndpoint = new SegmentEndpoint(planetModel, point);
|
||||||
endPoints.add(onlyEndpoint);
|
endPoints.add(onlyEndpoint);
|
||||||
this.edgePoints = new GeoPoint[] {point};
|
this.edgePoints = new GeoPoint[] {point};
|
||||||
return;
|
return;
|
||||||
|
@ -122,7 +122,7 @@ class GeoDegeneratePath extends GeoBasePath {
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
// Starting endpoint
|
// Starting endpoint
|
||||||
final SegmentEndpoint startEndpoint =
|
final SegmentEndpoint startEndpoint =
|
||||||
new SegmentEndpoint(currentSegment.start, currentSegment.startCutoffPlane);
|
new SegmentEndpoint(planetModel, currentSegment.start, currentSegment.startCutoffPlane);
|
||||||
endPoints.add(startEndpoint);
|
endPoints.add(startEndpoint);
|
||||||
this.edgePoints = new GeoPoint[] {currentSegment.start};
|
this.edgePoints = new GeoPoint[] {currentSegment.start};
|
||||||
continue;
|
continue;
|
||||||
|
@ -130,13 +130,14 @@ class GeoDegeneratePath extends GeoBasePath {
|
||||||
|
|
||||||
endPoints.add(
|
endPoints.add(
|
||||||
new SegmentEndpoint(
|
new SegmentEndpoint(
|
||||||
|
planetModel,
|
||||||
currentSegment.start,
|
currentSegment.start,
|
||||||
segments.get(i - 1).endCutoffPlane,
|
segments.get(i - 1).endCutoffPlane,
|
||||||
currentSegment.startCutoffPlane));
|
currentSegment.startCutoffPlane));
|
||||||
}
|
}
|
||||||
// Do final endpoint
|
// Do final endpoint
|
||||||
final PathSegment lastSegment = segments.get(segments.size() - 1);
|
final PathSegment lastSegment = segments.get(segments.size() - 1);
|
||||||
endPoints.add(new SegmentEndpoint(lastSegment.end, lastSegment.endCutoffPlane));
|
endPoints.add(new SegmentEndpoint(planetModel, lastSegment.end, lastSegment.endCutoffPlane));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -162,8 +163,7 @@ class GeoDegeneratePath extends GeoBasePath {
|
||||||
double closestDistance = Double.POSITIVE_INFINITY;
|
double closestDistance = Double.POSITIVE_INFINITY;
|
||||||
// Segments first
|
// Segments first
|
||||||
for (PathSegment segment : segments) {
|
for (PathSegment segment : segments) {
|
||||||
final double segmentDistance =
|
final double segmentDistance = segment.pathCenterDistance(distanceStyle, x, y, z);
|
||||||
segment.pathCenterDistance(planetModel, distanceStyle, x, y, z);
|
|
||||||
if (segmentDistance < closestDistance) {
|
if (segmentDistance < closestDistance) {
|
||||||
closestDistance = segmentDistance;
|
closestDistance = segmentDistance;
|
||||||
}
|
}
|
||||||
|
@ -196,14 +196,12 @@ class GeoDegeneratePath extends GeoBasePath {
|
||||||
// Look at the following segment, if any
|
// Look at the following segment, if any
|
||||||
if (segmentIndex < segments.size()) {
|
if (segmentIndex < segments.size()) {
|
||||||
final PathSegment segment = segments.get(segmentIndex++);
|
final PathSegment segment = segments.get(segmentIndex++);
|
||||||
final double segmentPathCenterDistance =
|
final double segmentPathCenterDistance = segment.pathCenterDistance(distanceStyle, x, y, z);
|
||||||
segment.pathCenterDistance(planetModel, distanceStyle, x, y, z);
|
|
||||||
if (segmentPathCenterDistance < minPathCenterDistance) {
|
if (segmentPathCenterDistance < minPathCenterDistance) {
|
||||||
minPathCenterDistance = segmentPathCenterDistance;
|
minPathCenterDistance = segmentPathCenterDistance;
|
||||||
bestDistance =
|
bestDistance =
|
||||||
distanceStyle.aggregateDistances(
|
distanceStyle.aggregateDistances(
|
||||||
currentDistance,
|
currentDistance, segment.nearestPathDistance(distanceStyle, x, y, z));
|
||||||
segment.nearestPathDistance(planetModel, distanceStyle, x, y, z));
|
|
||||||
}
|
}
|
||||||
currentDistance =
|
currentDistance =
|
||||||
distanceStyle.aggregateDistances(
|
distanceStyle.aggregateDistances(
|
||||||
|
@ -221,7 +219,7 @@ class GeoDegeneratePath extends GeoBasePath {
|
||||||
// (2) If the point is within any of the segment end circles along the path, return that value.
|
// (2) If the point is within any of the segment end circles along the path, return that value.
|
||||||
double currentDistance = 0.0;
|
double currentDistance = 0.0;
|
||||||
for (PathSegment segment : segments) {
|
for (PathSegment segment : segments) {
|
||||||
double distance = segment.pathDistance(planetModel, distanceStyle, x, y, z);
|
double distance = segment.pathDistance(distanceStyle, x, y, z);
|
||||||
if (distance != Double.POSITIVE_INFINITY)
|
if (distance != Double.POSITIVE_INFINITY)
|
||||||
return distanceStyle.fromAggregationForm(
|
return distanceStyle.fromAggregationForm(
|
||||||
distanceStyle.aggregateDistances(currentDistance, distance));
|
distanceStyle.aggregateDistances(currentDistance, distance));
|
||||||
|
@ -272,7 +270,7 @@ class GeoDegeneratePath extends GeoBasePath {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (final PathSegment segment : segments) {
|
for (final PathSegment segment : segments) {
|
||||||
final double newDistance = segment.outsideDistance(planetModel, distanceStyle, x, y, z);
|
final double newDistance = segment.outsideDistance(distanceStyle, x, y, z);
|
||||||
if (newDistance < minDistance) {
|
if (newDistance < minDistance) {
|
||||||
minDistance = newDistance;
|
minDistance = newDistance;
|
||||||
}
|
}
|
||||||
|
@ -317,11 +315,11 @@ class GeoDegeneratePath extends GeoBasePath {
|
||||||
// Since the endpoints are included in the path segments, we only need to do this if there are
|
// Since the endpoints are included in the path segments, we only need to do this if there are
|
||||||
// no path segments
|
// no path segments
|
||||||
if (endPoints.size() == 1) {
|
if (endPoints.size() == 1) {
|
||||||
return endPoints.get(0).intersects(planetModel, plane, notablePoints, bounds);
|
return endPoints.get(0).intersects(plane, notablePoints, bounds);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (final PathSegment pathSegment : segments) {
|
for (final PathSegment pathSegment : segments) {
|
||||||
if (pathSegment.intersects(planetModel, plane, notablePoints, bounds)) {
|
if (pathSegment.intersects(plane, notablePoints, bounds)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -353,10 +351,10 @@ class GeoDegeneratePath extends GeoBasePath {
|
||||||
// never more than 180 degrees longitude at a pop or we risk having the
|
// never more than 180 degrees longitude at a pop or we risk having the
|
||||||
// bounds object get itself inverted. So do the edges first.
|
// bounds object get itself inverted. So do the edges first.
|
||||||
for (PathSegment pathSegment : segments) {
|
for (PathSegment pathSegment : segments) {
|
||||||
pathSegment.getBounds(planetModel, bounds);
|
pathSegment.getBounds(bounds);
|
||||||
}
|
}
|
||||||
if (endPoints.size() == 1) {
|
if (endPoints.size() == 1) {
|
||||||
endPoints.get(0).getBounds(planetModel, bounds);
|
endPoints.get(0).getBounds(bounds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -396,7 +394,7 @@ class GeoDegeneratePath extends GeoBasePath {
|
||||||
* <li>Intersection. There are two cutoff planes, one for each end of the intersection.
|
* <li>Intersection. There are two cutoff planes, one for each end of the intersection.
|
||||||
* </ol>
|
* </ol>
|
||||||
*/
|
*/
|
||||||
private static class SegmentEndpoint {
|
private static class SegmentEndpoint extends GeoBaseBounds {
|
||||||
/** The center point of the endpoint */
|
/** The center point of the endpoint */
|
||||||
public final GeoPoint point;
|
public final GeoPoint point;
|
||||||
/** Pertinent cutoff planes from adjoining segments */
|
/** Pertinent cutoff planes from adjoining segments */
|
||||||
|
@ -407,9 +405,11 @@ class GeoDegeneratePath extends GeoBasePath {
|
||||||
/**
|
/**
|
||||||
* Constructor for case (1).
|
* Constructor for case (1).
|
||||||
*
|
*
|
||||||
|
* @param planetModel is the planet model.
|
||||||
* @param point is the center point.
|
* @param point is the center point.
|
||||||
*/
|
*/
|
||||||
public SegmentEndpoint(final GeoPoint point) {
|
public SegmentEndpoint(final PlanetModel planetModel, final GeoPoint point) {
|
||||||
|
super(planetModel);
|
||||||
this.point = point;
|
this.point = point;
|
||||||
this.cutoffPlanes = NO_MEMBERSHIP;
|
this.cutoffPlanes = NO_MEMBERSHIP;
|
||||||
}
|
}
|
||||||
|
@ -422,7 +422,9 @@ class GeoDegeneratePath extends GeoBasePath {
|
||||||
* @param cutoffPlane is the plane from the adjoining path segment marking the boundary between
|
* @param cutoffPlane is the plane from the adjoining path segment marking the boundary between
|
||||||
* this endpoint and that segment.
|
* this endpoint and that segment.
|
||||||
*/
|
*/
|
||||||
public SegmentEndpoint(final GeoPoint point, final SidedPlane cutoffPlane) {
|
public SegmentEndpoint(
|
||||||
|
final PlanetModel planetModel, final GeoPoint point, final SidedPlane cutoffPlane) {
|
||||||
|
super(planetModel);
|
||||||
this.point = point;
|
this.point = point;
|
||||||
this.cutoffPlanes = new Membership[] {new SidedPlane(cutoffPlane)};
|
this.cutoffPlanes = new Membership[] {new SidedPlane(cutoffPlane)};
|
||||||
}
|
}
|
||||||
|
@ -430,12 +432,17 @@ class GeoDegeneratePath extends GeoBasePath {
|
||||||
/**
|
/**
|
||||||
* Constructor for case (3). Generate an endpoint, given two cutoff planes.
|
* Constructor for case (3). Generate an endpoint, given two cutoff planes.
|
||||||
*
|
*
|
||||||
|
* @param planetModel is the planet model.
|
||||||
* @param point is the center.
|
* @param point is the center.
|
||||||
* @param cutoffPlane1 is one adjoining path segment cutoff plane.
|
* @param cutoffPlane1 is one adjoining path segment cutoff plane.
|
||||||
* @param cutoffPlane2 is another adjoining path segment cutoff plane.
|
* @param cutoffPlane2 is another adjoining path segment cutoff plane.
|
||||||
*/
|
*/
|
||||||
public SegmentEndpoint(
|
public SegmentEndpoint(
|
||||||
final GeoPoint point, final SidedPlane cutoffPlane1, final SidedPlane cutoffPlane2) {
|
final PlanetModel planetModel,
|
||||||
|
final GeoPoint point,
|
||||||
|
final SidedPlane cutoffPlane1,
|
||||||
|
final SidedPlane cutoffPlane2) {
|
||||||
|
super(planetModel);
|
||||||
this.point = point;
|
this.point = point;
|
||||||
this.cutoffPlanes =
|
this.cutoffPlanes =
|
||||||
new Membership[] {new SidedPlane(cutoffPlane1), new SidedPlane(cutoffPlane2)};
|
new Membership[] {new SidedPlane(cutoffPlane1), new SidedPlane(cutoffPlane2)};
|
||||||
|
@ -507,17 +514,13 @@ class GeoDegeneratePath extends GeoBasePath {
|
||||||
/**
|
/**
|
||||||
* Determine if this endpoint intersects a specified plane.
|
* Determine if this endpoint intersects a specified plane.
|
||||||
*
|
*
|
||||||
* @param planetModel is the planet model.
|
|
||||||
* @param p is the plane.
|
* @param p is the plane.
|
||||||
* @param notablePoints are the points associated with the plane.
|
* @param notablePoints are the points associated with the plane.
|
||||||
* @param bounds are any bounds which the intersection must lie within.
|
* @param bounds are any bounds which the intersection must lie within.
|
||||||
* @return true if there is a matching intersection.
|
* @return true if there is a matching intersection.
|
||||||
*/
|
*/
|
||||||
public boolean intersects(
|
public boolean intersects(
|
||||||
final PlanetModel planetModel,
|
final Plane p, final GeoPoint[] notablePoints, final Membership[] bounds) {
|
||||||
final Plane p,
|
|
||||||
final GeoPoint[] notablePoints,
|
|
||||||
final Membership[] bounds) {
|
|
||||||
// If not on the plane, no intersection
|
// If not on the plane, no intersection
|
||||||
if (!p.evaluateIsZero(point)) {
|
if (!p.evaluateIsZero(point)) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -572,13 +575,13 @@ class GeoDegeneratePath extends GeoBasePath {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** This is the pre-calculated data for a path segment. */
|
/** This is the pre-calculated data for a path segment. */
|
||||||
private static class PathSegment {
|
private static class PathSegment extends GeoBaseBounds {
|
||||||
/** Starting point of the segment */
|
/** Starting point of the segment */
|
||||||
public final GeoPoint start;
|
public final GeoPoint start;
|
||||||
/** End point of the segment */
|
/** End point of the segment */
|
||||||
public final GeoPoint end;
|
public final GeoPoint end;
|
||||||
/** Place to keep any complete segment distances we've calculated so far */
|
/** Place to keep any complete segment distances we've calculated so far */
|
||||||
public final Map<DistanceStyle, Double> fullDistanceCache = new HashMap<>();
|
public final Map<DistanceStyle, Double> fullDistanceCache = new ConcurrentHashMap<>(1);
|
||||||
/** Normalized plane connecting the two points and going through world center */
|
/** Normalized plane connecting the two points and going through world center */
|
||||||
public final Plane normalizedConnectingPlane;
|
public final Plane normalizedConnectingPlane;
|
||||||
/** Plane going through the center and start point, marking the start edge of the segment */
|
/** Plane going through the center and start point, marking the start edge of the segment */
|
||||||
|
@ -601,6 +604,7 @@ class GeoDegeneratePath extends GeoBasePath {
|
||||||
final GeoPoint start,
|
final GeoPoint start,
|
||||||
final GeoPoint end,
|
final GeoPoint end,
|
||||||
final Plane normalizedConnectingPlane) {
|
final Plane normalizedConnectingPlane) {
|
||||||
|
super(planetModel);
|
||||||
this.start = start;
|
this.start = start;
|
||||||
this.end = end;
|
this.end = end;
|
||||||
this.normalizedConnectingPlane = normalizedConnectingPlane;
|
this.normalizedConnectingPlane = normalizedConnectingPlane;
|
||||||
|
@ -618,7 +622,6 @@ class GeoDegeneratePath extends GeoBasePath {
|
||||||
* @return the distance metric, in aggregation form.
|
* @return the distance metric, in aggregation form.
|
||||||
*/
|
*/
|
||||||
public double fullPathDistance(final DistanceStyle distanceStyle) {
|
public double fullPathDistance(final DistanceStyle distanceStyle) {
|
||||||
synchronized (fullDistanceCache) {
|
|
||||||
Double dist = fullDistanceCache.get(distanceStyle);
|
Double dist = fullDistanceCache.get(distanceStyle);
|
||||||
if (dist == null) {
|
if (dist == null) {
|
||||||
dist =
|
dist =
|
||||||
|
@ -628,7 +631,6 @@ class GeoDegeneratePath extends GeoBasePath {
|
||||||
}
|
}
|
||||||
return dist.doubleValue();
|
return dist.doubleValue();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if point is within this segment.
|
* Check if point is within this segment.
|
||||||
|
@ -638,6 +640,7 @@ class GeoDegeneratePath extends GeoBasePath {
|
||||||
* @param z is the point z.
|
* @param z is the point z.
|
||||||
* @return true of within.
|
* @return true of within.
|
||||||
*/
|
*/
|
||||||
|
@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 startCutoffPlane.isWithin(x, y, z)
|
return startCutoffPlane.isWithin(x, y, z)
|
||||||
&& endCutoffPlane.isWithin(x, y, z)
|
&& endCutoffPlane.isWithin(x, y, z)
|
||||||
|
@ -645,9 +648,8 @@ class GeoDegeneratePath extends GeoBasePath {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compute path center distance.
|
* Compute path center distance (distance from path to current point).
|
||||||
*
|
*
|
||||||
* @param planetModel is the planet model.
|
|
||||||
* @param distanceStyle is the distance style.
|
* @param distanceStyle is the distance style.
|
||||||
* @param x is the point x.
|
* @param x is the point x.
|
||||||
* @param y is the point y.
|
* @param y is the point y.
|
||||||
|
@ -655,11 +657,7 @@ class GeoDegeneratePath extends GeoBasePath {
|
||||||
* @return the distance metric, or Double.POSITIVE_INFINITY if outside this segment
|
* @return the distance metric, or Double.POSITIVE_INFINITY if outside this segment
|
||||||
*/
|
*/
|
||||||
public double pathCenterDistance(
|
public double pathCenterDistance(
|
||||||
final PlanetModel planetModel,
|
final DistanceStyle distanceStyle, final double x, final double y, final double z) {
|
||||||
final DistanceStyle distanceStyle,
|
|
||||||
final double x,
|
|
||||||
final double y,
|
|
||||||
final double z) {
|
|
||||||
// First, if this point is outside the endplanes of the segment, return POSITIVE_INFINITY.
|
// First, if this point is outside the endplanes of the segment, return POSITIVE_INFINITY.
|
||||||
if (!startCutoffPlane.isWithin(x, y, z) || !endCutoffPlane.isWithin(x, y, z)) {
|
if (!startCutoffPlane.isWithin(x, y, z) || !endCutoffPlane.isWithin(x, y, z)) {
|
||||||
return Double.POSITIVE_INFINITY;
|
return Double.POSITIVE_INFINITY;
|
||||||
|
@ -704,9 +702,8 @@ class GeoDegeneratePath extends GeoBasePath {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compute nearest path distance.
|
* Compute nearest path distance (distance from start of segment to center line point adjacent).
|
||||||
*
|
*
|
||||||
* @param planetModel is the planet model.
|
|
||||||
* @param distanceStyle is the distance style.
|
* @param distanceStyle is the distance style.
|
||||||
* @param x is the point x.
|
* @param x is the point x.
|
||||||
* @param y is the point y.
|
* @param y is the point y.
|
||||||
|
@ -715,11 +712,7 @@ class GeoDegeneratePath extends GeoBasePath {
|
||||||
* segment
|
* segment
|
||||||
*/
|
*/
|
||||||
public double nearestPathDistance(
|
public double nearestPathDistance(
|
||||||
final PlanetModel planetModel,
|
final DistanceStyle distanceStyle, final double x, final double y, final double z) {
|
||||||
final DistanceStyle distanceStyle,
|
|
||||||
final double x,
|
|
||||||
final double y,
|
|
||||||
final double z) {
|
|
||||||
// First, if this point is outside the endplanes of the segment, return POSITIVE_INFINITY.
|
// First, if this point is outside the endplanes of the segment, return POSITIVE_INFINITY.
|
||||||
if (!startCutoffPlane.isWithin(x, y, z) || !endCutoffPlane.isWithin(x, y, z)) {
|
if (!startCutoffPlane.isWithin(x, y, z) || !endCutoffPlane.isWithin(x, y, z)) {
|
||||||
return Double.POSITIVE_INFINITY;
|
return Double.POSITIVE_INFINITY;
|
||||||
|
@ -775,11 +768,7 @@ class GeoDegeneratePath extends GeoBasePath {
|
||||||
* @return the distance metric, in aggregation form.
|
* @return the distance metric, in aggregation form.
|
||||||
*/
|
*/
|
||||||
public double pathDistance(
|
public double pathDistance(
|
||||||
final PlanetModel planetModel,
|
final DistanceStyle distanceStyle, final double x, final double y, final double z) {
|
||||||
final DistanceStyle distanceStyle,
|
|
||||||
final double x,
|
|
||||||
final double y,
|
|
||||||
final double z) {
|
|
||||||
if (!isWithin(x, y, z)) return Double.POSITIVE_INFINITY;
|
if (!isWithin(x, y, z)) return Double.POSITIVE_INFINITY;
|
||||||
|
|
||||||
// (1) Compute normalizedPerpPlane. If degenerate, then return point distance from start to
|
// (1) Compute normalizedPerpPlane. If degenerate, then return point distance from start to
|
||||||
|
@ -839,11 +828,7 @@ class GeoDegeneratePath extends GeoBasePath {
|
||||||
* @return the distance metric.
|
* @return the distance metric.
|
||||||
*/
|
*/
|
||||||
public double outsideDistance(
|
public double outsideDistance(
|
||||||
final PlanetModel planetModel,
|
final DistanceStyle distanceStyle, final double x, final double y, final double z) {
|
||||||
final DistanceStyle distanceStyle,
|
|
||||||
final double x,
|
|
||||||
final double y,
|
|
||||||
final double z) {
|
|
||||||
final double distance =
|
final double distance =
|
||||||
distanceStyle.computeDistance(
|
distanceStyle.computeDistance(
|
||||||
planetModel, normalizedConnectingPlane, x, y, z, startCutoffPlane, endCutoffPlane);
|
planetModel, normalizedConnectingPlane, x, y, z, startCutoffPlane, endCutoffPlane);
|
||||||
|
@ -862,10 +847,7 @@ class GeoDegeneratePath extends GeoBasePath {
|
||||||
* @return true if there is a matching intersection.
|
* @return true if there is a matching intersection.
|
||||||
*/
|
*/
|
||||||
public boolean intersects(
|
public boolean intersects(
|
||||||
final PlanetModel planetModel,
|
final Plane p, final GeoPoint[] notablePoints, final Membership[] bounds) {
|
||||||
final Plane p,
|
|
||||||
final GeoPoint[] notablePoints,
|
|
||||||
final Membership[] bounds) {
|
|
||||||
return normalizedConnectingPlane.intersects(
|
return normalizedConnectingPlane.intersects(
|
||||||
planetModel,
|
planetModel,
|
||||||
p,
|
p,
|
||||||
|
@ -893,7 +875,9 @@ class GeoDegeneratePath extends GeoBasePath {
|
||||||
* @param planetModel is the planet model.
|
* @param planetModel is the planet model.
|
||||||
* @param bounds are the bounds to be modified.
|
* @param bounds are the bounds to be modified.
|
||||||
*/
|
*/
|
||||||
public void getBounds(final PlanetModel planetModel, Bounds bounds) {
|
@Override
|
||||||
|
public void getBounds(final Bounds bounds) {
|
||||||
|
super.getBounds(bounds);
|
||||||
// We need to do all bounding planes as well as corner points
|
// We need to do all bounding planes as well as corner points
|
||||||
bounds
|
bounds
|
||||||
.addPoint(start)
|
.addPoint(start)
|
||||||
|
|
|
@ -351,7 +351,11 @@ class GeoStandardPath extends GeoBasePath {
|
||||||
if (rootComponent == null) {
|
if (rootComponent == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return rootComponent.intersects(plane, notablePoints, bounds);
|
final boolean rval = rootComponent.intersects(plane, notablePoints, bounds);
|
||||||
|
if (rval) {
|
||||||
|
System.out.println("Plane " + plane + " within its bounds intersects " + rootComponent);
|
||||||
|
}
|
||||||
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -359,7 +363,11 @@ class GeoStandardPath extends GeoBasePath {
|
||||||
if (rootComponent == null) {
|
if (rootComponent == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return rootComponent.intersects(geoShape);
|
final boolean rval = rootComponent.intersects(geoShape);
|
||||||
|
if (rval) {
|
||||||
|
System.out.println("Shape " + geoShape + " intersects " + rootComponent);
|
||||||
|
}
|
||||||
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -430,6 +438,12 @@ class GeoStandardPath extends GeoBasePath {
|
||||||
*/
|
*/
|
||||||
boolean isWithin(final double x, final double y, final double z);
|
boolean isWithin(final double x, final double y, final double z);
|
||||||
|
|
||||||
|
/** Check if point is within this section (within cutoff planes). */
|
||||||
|
boolean isWithinSection(final Vector point);
|
||||||
|
|
||||||
|
/** Check if point is within this section (within cutoff planes). */
|
||||||
|
boolean isWithinSection(final double x, final double y, final double z);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the starting distance along the path for this path element.
|
* Retrieve the starting distance along the path for this path element.
|
||||||
*
|
*
|
||||||
|
@ -498,28 +512,28 @@ class GeoStandardPath extends GeoBasePath {
|
||||||
final DistanceStyle distanceStyle, final double x, final double y, final double z);
|
final DistanceStyle distanceStyle, final double x, final double y, final double z);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compute nearest path distance.
|
* Compute nearest path distance (distance from start of segment to point adjacent the one
|
||||||
|
* specitied, if reachable by this segment).
|
||||||
*
|
*
|
||||||
* @param distanceStyle is the distance style.
|
* @param distanceStyle is the distance style.
|
||||||
* @param x is the point x.
|
* @param x is the point x.
|
||||||
* @param y is the point y.
|
* @param y is the point y.
|
||||||
* @param z is the point z.
|
* @param z is the point z.
|
||||||
* @return the distance metric (always value zero), in aggregation form, or POSITIVE_INFINITY if
|
* @return the distance metric, in aggregation form.
|
||||||
* the point is not within the bounds of the endpoint.
|
|
||||||
*/
|
*/
|
||||||
double nearestPathDistance(
|
double nearestPathDistance(
|
||||||
final DistanceStyle distanceStyle, final double x, final double y, final double z);
|
final DistanceStyle distanceStyle, final double x, final double y, final double z);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compute path center distance. Returns POSITIVE_INFINITY if the point is outside of the
|
* Compute path center distance (distance from the point to center of the path, if reachable by
|
||||||
* bounds.
|
* this segment).
|
||||||
*
|
*
|
||||||
* @param distanceStyle is the distance style.
|
* @param distanceStyle is the distance style.
|
||||||
* @param x is the point x.
|
* @param x is the point x.
|
||||||
* @param y is the point y.
|
* @param y is the point y.
|
||||||
* @param z is the point z.
|
* @param z is the point z.
|
||||||
* @return the distance metric, or POSITIVE_INFINITY if the point is not within the bounds of
|
* @return the distance metric, or POSITIVE_INFINITY if the point is not within the bounds of
|
||||||
* the endpoint.
|
* the path segment.
|
||||||
*/
|
*/
|
||||||
double pathCenterDistance(
|
double pathCenterDistance(
|
||||||
final DistanceStyle distanceStyle, final double x, final double y, final double z);
|
final DistanceStyle distanceStyle, final double x, final double y, final double z);
|
||||||
|
@ -611,6 +625,16 @@ class GeoStandardPath extends GeoBasePath {
|
||||||
return child1.isWithin(x, y, z) || child2.isWithin(x, y, z);
|
return child1.isWithin(x, y, z) || child2.isWithin(x, y, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isWithinSection(final Vector point) {
|
||||||
|
return child1.isWithinSection(point) || child2.isWithinSection(point);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isWithinSection(final double x, final double y, final double z) {
|
||||||
|
return child1.isWithinSection(x, y, z) || child2.isWithinSection(x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double getStartingDistance(final DistanceStyle distanceStyle) {
|
public double getStartingDistance(final DistanceStyle distanceStyle) {
|
||||||
return child1.getStartingDistance(distanceStyle);
|
return child1.getStartingDistance(distanceStyle);
|
||||||
|
@ -632,7 +656,7 @@ class GeoStandardPath extends GeoBasePath {
|
||||||
@Override
|
@Override
|
||||||
public double nearestDistance(
|
public double nearestDistance(
|
||||||
final DistanceStyle distanceStyle, final double x, final double y, final double z) {
|
final DistanceStyle distanceStyle, final double x, final double y, final double z) {
|
||||||
if (!isWithin(x, y, z)) {
|
if (!isWithinSection(x, y, z)) {
|
||||||
return Double.POSITIVE_INFINITY;
|
return Double.POSITIVE_INFINITY;
|
||||||
}
|
}
|
||||||
return Math.min(
|
return Math.min(
|
||||||
|
@ -672,7 +696,7 @@ class GeoStandardPath extends GeoBasePath {
|
||||||
@Override
|
@Override
|
||||||
public double nearestPathDistance(
|
public double nearestPathDistance(
|
||||||
final DistanceStyle distanceStyle, final double x, final double y, final double z) {
|
final DistanceStyle distanceStyle, final double x, final double y, final double z) {
|
||||||
if (!isWithin(x, y, z)) {
|
if (!isWithinSection(x, y, z)) {
|
||||||
return Double.POSITIVE_INFINITY;
|
return Double.POSITIVE_INFINITY;
|
||||||
}
|
}
|
||||||
return Math.min(
|
return Math.min(
|
||||||
|
@ -683,7 +707,7 @@ class GeoStandardPath extends GeoBasePath {
|
||||||
@Override
|
@Override
|
||||||
public double pathCenterDistance(
|
public double pathCenterDistance(
|
||||||
final DistanceStyle distanceStyle, final double x, final double y, final double z) {
|
final DistanceStyle distanceStyle, final double x, final double y, final double z) {
|
||||||
if (!isWithin(x, y, z)) {
|
if (!isWithinSection(x, y, z)) {
|
||||||
return Double.POSITIVE_INFINITY;
|
return Double.POSITIVE_INFINITY;
|
||||||
}
|
}
|
||||||
return Math.min(
|
return Math.min(
|
||||||
|
@ -703,8 +727,17 @@ class GeoStandardPath extends GeoBasePath {
|
||||||
@Override
|
@Override
|
||||||
public boolean intersects(
|
public boolean intersects(
|
||||||
final Plane p, final GeoPoint[] notablePoints, final Membership[] bounds) {
|
final Plane p, final GeoPoint[] notablePoints, final Membership[] bounds) {
|
||||||
return child1.intersects(p, notablePoints, bounds)
|
final boolean rval =
|
||||||
|
child1.intersects(p, notablePoints, bounds)
|
||||||
|| child2.intersects(p, notablePoints, bounds);
|
|| child2.intersects(p, notablePoints, bounds);
|
||||||
|
if (rval) {
|
||||||
|
if (child1.intersects(p, notablePoints, bounds)) {
|
||||||
|
System.out.println("Plane " + p + " intersected " + child1);
|
||||||
|
} else if (child2.intersects(p, notablePoints, bounds)) {
|
||||||
|
System.out.println("Plane " + p + " intersected " + child2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -769,6 +802,16 @@ class GeoStandardPath extends GeoBasePath {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isWithinSection(final double x, final double y, final double z) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isWithinSection(final Vector point) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double getStartingDistance(DistanceStyle distanceStyle) {
|
public double getStartingDistance(DistanceStyle distanceStyle) {
|
||||||
if (previous == null) {
|
if (previous == null) {
|
||||||
|
@ -793,7 +836,7 @@ class GeoStandardPath extends GeoBasePath {
|
||||||
@Override
|
@Override
|
||||||
public double nearestDistance(
|
public double nearestDistance(
|
||||||
final DistanceStyle distanceStyle, final double x, final double y, final double z) {
|
final DistanceStyle distanceStyle, final double x, final double y, final double z) {
|
||||||
if (!isWithin(x, y, z)) {
|
if (!isWithinSection(x, y, z)) {
|
||||||
return Double.POSITIVE_INFINITY;
|
return Double.POSITIVE_INFINITY;
|
||||||
}
|
}
|
||||||
return distanceStyle.fromAggregationForm(getStartingDistance(distanceStyle));
|
return distanceStyle.fromAggregationForm(getStartingDistance(distanceStyle));
|
||||||
|
@ -827,16 +870,16 @@ class GeoStandardPath extends GeoBasePath {
|
||||||
@Override
|
@Override
|
||||||
public double nearestPathDistance(
|
public double nearestPathDistance(
|
||||||
final DistanceStyle distanceStyle, final double x, final double y, final double z) {
|
final DistanceStyle distanceStyle, final double x, final double y, final double z) {
|
||||||
if (!isWithin(x, y, z)) {
|
if (!isWithinSection(x, y, z)) {
|
||||||
return Double.POSITIVE_INFINITY;
|
return Double.POSITIVE_INFINITY;
|
||||||
}
|
}
|
||||||
return distanceStyle.toAggregationForm(0.0);
|
return distanceStyle.toAggregationForm(distanceStyle.computeDistance(this.point, x, y, z));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double pathCenterDistance(
|
public double pathCenterDistance(
|
||||||
final DistanceStyle distanceStyle, final double x, final double y, final double z) {
|
final DistanceStyle distanceStyle, final double x, final double y, final double z) {
|
||||||
if (!isWithin(x, y, z)) {
|
if (!isWithinSection(x, y, z)) {
|
||||||
return Double.POSITIVE_INFINITY;
|
return Double.POSITIVE_INFINITY;
|
||||||
}
|
}
|
||||||
return distanceStyle.computeDistance(this.point, x, y, z);
|
return distanceStyle.computeDistance(this.point, x, y, z);
|
||||||
|
@ -1023,6 +1066,16 @@ class GeoStandardPath extends GeoBasePath {
|
||||||
return cutoffPlane.isWithin(x, y, z) && super.isWithin(x, y, z);
|
return cutoffPlane.isWithin(x, y, z) && super.isWithin(x, y, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isWithinSection(final Vector point) {
|
||||||
|
return cutoffPlane.isWithin(point);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isWithinSection(final double x, final double y, final double z) {
|
||||||
|
return cutoffPlane.isWithin(x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean intersects(
|
public boolean intersects(
|
||||||
final Plane p, final GeoPoint[] notablePoints, final Membership[] bounds) {
|
final Plane p, final GeoPoint[] notablePoints, final Membership[] bounds) {
|
||||||
|
@ -1035,6 +1088,28 @@ class GeoStandardPath extends GeoBasePath {
|
||||||
return geoShape.intersects(circlePlane, this.notablePoints, this.cutoffPlanes);
|
return geoShape.intersects(circlePlane, this.notablePoints, this.cutoffPlanes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double nearestPathDistance(
|
||||||
|
final DistanceStyle distanceStyle, final double x, final double y, final double z) {
|
||||||
|
for (final Membership cutoff : cutoffPlanes) {
|
||||||
|
if (!cutoff.isWithin(x, y, z)) {
|
||||||
|
return Double.POSITIVE_INFINITY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return super.nearestPathDistance(distanceStyle, x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double pathCenterDistance(
|
||||||
|
final DistanceStyle distanceStyle, final double x, final double y, final double z) {
|
||||||
|
for (final Membership cutoff : cutoffPlanes) {
|
||||||
|
if (!cutoff.isWithin(x, y, z)) {
|
||||||
|
return Double.POSITIVE_INFINITY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return super.pathCenterDistance(distanceStyle, x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void getBounds(final Bounds bounds) {
|
public void getBounds(final Bounds bounds) {
|
||||||
super.getBounds(bounds);
|
super.getBounds(bounds);
|
||||||
|
@ -1144,6 +1219,26 @@ class GeoStandardPath extends GeoBasePath {
|
||||||
return circlePlane1.isWithin(x, y, z) || circlePlane2.isWithin(x, y, z);
|
return circlePlane1.isWithin(x, y, z) || circlePlane2.isWithin(x, y, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isWithinSection(final Vector point) {
|
||||||
|
for (final Membership m : cutoffPlanes) {
|
||||||
|
if (!m.isWithin(point)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isWithinSection(final double x, final double y, final double z) {
|
||||||
|
for (final Membership m : cutoffPlanes) {
|
||||||
|
if (!m.isWithin(x, y, z)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean intersects(
|
public boolean intersects(
|
||||||
final Plane p, final GeoPoint[] notablePoints, final Membership[] bounds) {
|
final Plane p, final GeoPoint[] notablePoints, final Membership[] bounds) {
|
||||||
|
@ -1159,6 +1254,28 @@ class GeoStandardPath extends GeoBasePath {
|
||||||
|| geoShape.intersects(circlePlane2, this.notablePoints2, this.cutoffPlanes);
|
|| geoShape.intersects(circlePlane2, this.notablePoints2, this.cutoffPlanes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double nearestPathDistance(
|
||||||
|
final DistanceStyle distanceStyle, final double x, final double y, final double z) {
|
||||||
|
for (final Membership cutoff : cutoffPlanes) {
|
||||||
|
if (!cutoff.isWithin(x, y, z)) {
|
||||||
|
return Double.POSITIVE_INFINITY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return super.nearestPathDistance(distanceStyle, x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double pathCenterDistance(
|
||||||
|
final DistanceStyle distanceStyle, final double x, final double y, final double z) {
|
||||||
|
for (final Membership cutoff : cutoffPlanes) {
|
||||||
|
if (!cutoff.isWithin(x, y, z)) {
|
||||||
|
return Double.POSITIVE_INFINITY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return super.pathCenterDistance(distanceStyle, x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void getBounds(final Bounds bounds) {
|
public void getBounds(final Bounds bounds) {
|
||||||
super.getBounds(bounds);
|
super.getBounds(bounds);
|
||||||
|
@ -1311,6 +1428,16 @@ class GeoStandardPath extends GeoBasePath {
|
||||||
return isWithin(v.x, v.y, v.z);
|
return isWithin(v.x, v.y, v.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isWithinSection(final Vector point) {
|
||||||
|
return startCutoffPlane.isWithin(point) && endCutoffPlane.isWithin(point);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isWithinSection(final double x, final double y, final double z) {
|
||||||
|
return startCutoffPlane.isWithin(x, y, z) && endCutoffPlane.isWithin(x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double getStartingDistance(final DistanceStyle distanceStyle) {
|
public double getStartingDistance(final DistanceStyle distanceStyle) {
|
||||||
Double dist = startDistanceCache.get(distanceStyle);
|
Double dist = startDistanceCache.get(distanceStyle);
|
||||||
|
@ -1338,12 +1465,14 @@ class GeoStandardPath extends GeoBasePath {
|
||||||
@Override
|
@Override
|
||||||
public double nearestDistance(
|
public double nearestDistance(
|
||||||
final DistanceStyle distanceStyle, final double x, final double y, final double z) {
|
final DistanceStyle distanceStyle, final double x, final double y, final double z) {
|
||||||
if (!isWithin(x, y, z)) {
|
if (!isWithinSection(x, y, z)) {
|
||||||
return Double.POSITIVE_INFINITY;
|
return Double.POSITIVE_INFINITY;
|
||||||
}
|
}
|
||||||
return distanceStyle.fromAggregationForm(
|
return distanceStyle.fromAggregationForm(
|
||||||
distanceStyle.aggregateDistances(
|
distanceStyle.aggregateDistances(
|
||||||
getStartingDistance(distanceStyle), nearestPathDistance(distanceStyle, x, y, z)));
|
distanceStyle.aggregateDistances(
|
||||||
|
getStartingDistance(distanceStyle), nearestPathDistance(distanceStyle, x, y, z)),
|
||||||
|
pathCenterDistance(distanceStyle, x, y, z)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private double computeStartingDistance(final DistanceStyle distanceStyle) {
|
private double computeStartingDistance(final DistanceStyle distanceStyle) {
|
||||||
|
@ -1358,10 +1487,10 @@ class GeoStandardPath extends GeoBasePath {
|
||||||
public double pathCenterDistance(
|
public double pathCenterDistance(
|
||||||
final DistanceStyle distanceStyle, final double x, final double y, final double z) {
|
final DistanceStyle distanceStyle, final double x, final double y, final double z) {
|
||||||
// Computes the distance to the path center from the specified point, or returns
|
// Computes the distance to the path center from the specified point, or returns
|
||||||
// POSITIVE_INFINITY if the point is outside the path.
|
// POSITIVE_INFINITY if the point is outside the path section.
|
||||||
|
|
||||||
// First, if this point is outside the endplanes of the segment, return POSITIVE_INFINITY.
|
// First, if this point is outside the endplanes of the segment, return POSITIVE_INFINITY.
|
||||||
if (!startCutoffPlane.isWithin(x, y, z) || !endCutoffPlane.isWithin(x, y, z)) {
|
if (!isWithinSection(x, y, z)) {
|
||||||
return Double.POSITIVE_INFINITY;
|
return Double.POSITIVE_INFINITY;
|
||||||
}
|
}
|
||||||
// (1) Compute normalizedPerpPlane. If degenerate, then there is no such plane, which means
|
// (1) Compute normalizedPerpPlane. If degenerate, then there is no such plane, which means
|
||||||
|
@ -1400,7 +1529,7 @@ class GeoStandardPath extends GeoBasePath {
|
||||||
"Can't find world intersection for point x=" + x + " y=" + y + " z=" + z);
|
"Can't find world intersection for point x=" + x + " y=" + y + " z=" + z);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return distanceStyle.computeDistance(thePoint, x, y, z);
|
return distanceStyle.toAggregationForm(distanceStyle.computeDistance(thePoint, x, y, z));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1408,7 +1537,10 @@ class GeoStandardPath extends GeoBasePath {
|
||||||
final DistanceStyle distanceStyle, final double x, final double y, final double z) {
|
final DistanceStyle distanceStyle, final double x, final double y, final double z) {
|
||||||
// Computes the distance along the path to a point on the path where a perpendicular plane
|
// Computes the distance along the path to a point on the path where a perpendicular plane
|
||||||
// goes through the specified point.
|
// goes through the specified point.
|
||||||
|
// First, if this point is outside the endplanes of the segment, return POSITIVE_INFINITY.
|
||||||
|
if (!isWithinSection(x, y, z)) {
|
||||||
|
return Double.POSITIVE_INFINITY;
|
||||||
|
}
|
||||||
// (1) Compute normalizedPerpPlane. If degenerate, then there is no such plane, which means
|
// (1) Compute normalizedPerpPlane. If degenerate, then there is no such plane, which means
|
||||||
// that the point given is insufficient to distinguish between a family of such planes.
|
// that the point given is insufficient to distinguish between a family of such planes.
|
||||||
// This can happen only if the point is one of the "poles", imagining the normalized plane
|
// This can happen only if the point is one of the "poles", imagining the normalized plane
|
||||||
|
@ -1452,7 +1584,7 @@ class GeoStandardPath extends GeoBasePath {
|
||||||
@Override
|
@Override
|
||||||
public double pathDeltaDistance(
|
public double pathDeltaDistance(
|
||||||
final DistanceStyle distanceStyle, final double x, final double y, final double z) {
|
final DistanceStyle distanceStyle, final double x, final double y, final double z) {
|
||||||
// Returns 2x the pathCenterDistance. Represents the cost of an "excursion" to and
|
// Represents the cost of an "excursion" to and
|
||||||
// from the path.
|
// from the path.
|
||||||
|
|
||||||
if (!isWithin(x, y, z)) {
|
if (!isWithin(x, y, z)) {
|
||||||
|
|
|
@ -431,6 +431,52 @@ public class TestGeoPath extends LuceneTestCase {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testInterpolation2() {
|
||||||
|
final double lat = 52.5665;
|
||||||
|
final double lon = 13.3076;
|
||||||
|
final double[] pathLats =
|
||||||
|
new double[] {
|
||||||
|
52.5355, 52.54, 52.5626, 52.5665, 52.6007, 52.6135, 52.6303, 52.6651, 52.7074
|
||||||
|
};
|
||||||
|
final double[] pathLons =
|
||||||
|
new double[] {
|
||||||
|
13.3634, 13.3704, 13.3307, 13.3076, 13.2806, 13.2484, 13.2406, 13.241, 13.1926
|
||||||
|
};
|
||||||
|
|
||||||
|
final GeoPoint carPoint =
|
||||||
|
new GeoPoint(PlanetModel.SPHERE, Math.toRadians(lat), Math.toRadians(lon));
|
||||||
|
final GeoPoint[] pathPoints = new GeoPoint[pathLats.length];
|
||||||
|
for (int i = 0; i < pathPoints.length; i++) {
|
||||||
|
pathPoints[i] =
|
||||||
|
new GeoPoint(
|
||||||
|
PlanetModel.SPHERE, Math.toRadians(pathLats[i]), Math.toRadians(pathLons[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Construct a path with no width
|
||||||
|
final GeoPath thisPath = GeoPathFactory.makeGeoPath(PlanetModel.SPHERE, 0.0, pathPoints);
|
||||||
|
// Construct a path with a width
|
||||||
|
final GeoPath legacyPath = GeoPathFactory.makeGeoPath(PlanetModel.SPHERE, 1e-6, pathPoints);
|
||||||
|
|
||||||
|
// Compute the inside distance to the atPoint using zero-width path
|
||||||
|
final double distance = thisPath.computeNearestDistance(DistanceStyle.ARC, carPoint);
|
||||||
|
// Compute the inside distance using legacy path
|
||||||
|
final double legacyDistance = legacyPath.computeNearestDistance(DistanceStyle.ARC, carPoint);
|
||||||
|
|
||||||
|
// Compute the inside distance using the legacy formula
|
||||||
|
final double oldFormulaDistance = thisPath.computeDistance(DistanceStyle.ARC, carPoint);
|
||||||
|
// Compute the inside distance using the legacy formula with the legacy shape
|
||||||
|
final double oldFormulaLegacyDistance = legacyPath.computeDistance(DistanceStyle.ARC, carPoint);
|
||||||
|
|
||||||
|
// These should be about the same
|
||||||
|
assertEquals(legacyDistance, distance, 1e-12);
|
||||||
|
|
||||||
|
assertEquals(oldFormulaLegacyDistance, oldFormulaDistance, 1e-12);
|
||||||
|
|
||||||
|
// Since the point we picked is actually on the path, this should also be true
|
||||||
|
assertEquals(oldFormulaDistance, distance, 1e-12);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testIdenticalPoints() {
|
public void testIdenticalPoints() {
|
||||||
PlanetModel planetModel = PlanetModel.WGS84;
|
PlanetModel planetModel = PlanetModel.WGS84;
|
||||||
|
|
Loading…
Reference in New Issue