Skip to content

Move sloppySin into SloppyMath from GeoUtils #14516

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 14 commits into
base: main
Choose a base branch
from
25 changes: 0 additions & 25 deletions lucene/core/src/java/org/apache/lucene/geo/GeoUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
*/
package org.apache.lucene.geo;

import static org.apache.lucene.util.SloppyMath.cos;
import static org.apache.lucene.util.SloppyMath.haversinMeters;

import org.apache.lucene.index.PointValues;
Expand Down Expand Up @@ -87,30 +86,6 @@ public static void checkLongitude(double longitude) {
}
}

// some sloppyish stuff, do we really need this to be done in a sloppy way?
// unless it is performance sensitive, we should try to remove.
private static final double PIO2 = Math.PI / 2D;

/**
* Returns the trigonometric sine of an angle converted as a cos operation.
*
* <p>Note that this is not quite right... e.g. sin(0) != 0
*
* <p>Special cases:
*
* <ul>
* <li>If the argument is {@code NaN} or an infinity, then the result is {@code NaN}.
* </ul>
*
* @param a an angle, in radians.
* @return the sine of the argument.
* @see Math#sin(double)
*/
// TODO: deprecate/remove this? at least its no longer public.
public static double sloppySin(double a) {
return cos(a - PIO2);
}

/**
* binary search to find the exact sortKey needed to match the specified radius any sort key lte
* this is a query match.
Expand Down
32 changes: 18 additions & 14 deletions lucene/core/src/java/org/apache/lucene/geo/Rectangle.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,6 @@
*/
package org.apache.lucene.geo;

import static java.lang.Math.PI;
import static java.lang.Math.max;
import static java.lang.Math.min;
import static org.apache.lucene.geo.GeoUtils.EARTH_MEAN_RADIUS_METERS;
import static org.apache.lucene.geo.GeoUtils.MAX_LAT_INCL;
import static org.apache.lucene.geo.GeoUtils.MAX_LAT_RADIANS;
Expand All @@ -28,9 +25,6 @@
import static org.apache.lucene.geo.GeoUtils.MIN_LON_RADIANS;
import static org.apache.lucene.geo.GeoUtils.checkLatitude;
import static org.apache.lucene.geo.GeoUtils.checkLongitude;
import static org.apache.lucene.geo.GeoUtils.sloppySin;
import static org.apache.lucene.util.SloppyMath.asin;
import static org.apache.lucene.util.SloppyMath.cos;

/** Represents a lat/lon rectangle. */
public class Rectangle extends LatLonGeometry {
Expand Down Expand Up @@ -106,34 +100,44 @@ public static boolean containsPoint(
return lat >= minLat && lat <= maxLat && lon >= minLon && lon <= maxLon;
}

/** Compute Bounding Box for a circle using WGS-84 parameters */
/**
* Creates a bounding box for a circle using standard trigonometric functions.
*
* @param centerLat Latitude of center point in degrees [-90, 90]
* @param centerLon Longitude of center point in degrees [-180, 180]
* @param radiusMeters Radius in meters
* @return Rectangle representing the bounding box
*/
public static Rectangle fromPointDistance(
final double centerLat, final double centerLon, final double radiusMeters) {
checkLatitude(centerLat);
checkLongitude(centerLon);

final double radLat = Math.toRadians(centerLat);
final double radLon = Math.toRadians(centerLon);
// LUCENE-7143
// Small buffer added for safety (from original LUCENE-7143)
double radDistance = (radiusMeters + 7E-2) / EARTH_MEAN_RADIUS_METERS;

double minLat = radLat - radDistance;
double maxLat = radLat + radDistance;
double minLon;
double maxLon;

if (minLat > MIN_LAT_RADIANS && maxLat < MAX_LAT_RADIANS) {
double deltaLon = asin(sloppySin(radDistance) / cos(radLat));
// Standard case - use accurate Math.sin
double deltaLon = Math.asin(Math.sin(radDistance) / Math.cos(radLat));
minLon = radLon - deltaLon;
if (minLon < MIN_LON_RADIANS) {
minLon += 2d * PI;
minLon += 2d * Math.PI;
}
maxLon = radLon + deltaLon;
if (maxLon > MAX_LON_RADIANS) {
maxLon -= 2d * PI;
maxLon -= 2d * Math.PI;
}
} else {
// a pole is within the distance
minLat = max(minLat, MIN_LAT_RADIANS);
maxLat = min(maxLat, MAX_LAT_RADIANS);
// Pole is within the distance
minLat = Math.max(minLat, MIN_LAT_RADIANS);
maxLat = Math.min(maxLat, MAX_LAT_RADIANS);
minLon = MIN_LON_RADIANS;
maxLon = MAX_LON_RADIANS;
}
Expand Down