余弦定理の球面法則を使用できます。
計算には地球の半径を使用する必要があります。
EARTH_RADIUS_KM = 6371;
ここで、openstreetmap.orgからのOsmMercator.javaへの私の貢献から:
/**
* Gets the distance using Spherical law of cosines.
*
* @param la1 the Latitude in degrees
* @param lo1 the Longitude in degrees
* @param la2 the Latitude from 2nd coordinate in degrees
* @param lo2 the Longitude from 2nd coordinate in degrees
* @return the distance
*/
public static double getDistance(double la1, double lo1, double la2, double lo2) {
double aStartLat = Math.toRadians(la1);
double aStartLong = Math.toRadians(lo1);
double aEndLat =Math.toRadians(la2);
double aEndLong = Math.toRadians(lo2);
double distance = Math.acos(Math.sin(aStartLat) * Math.sin(aEndLat)
+ Math.cos(aStartLat) * Math.cos(aEndLat)
* Math.cos(aEndLong - aStartLong));
return (EARTH_RADIUS_KM * distance);
}
あなたがする必要があるのは、内積で最も近い点を見つけて、それを距離方程式で使用することです。
最も近いポイントの例は次のとおりです。
double[] nearestPointSegment (double[] a, double[] b, double[] c)
{
double[] t= nearestPointGreatCircle(a,b,c);
if (onSegment(a,b,t))
return t;
return (distance(a,c) < distance(b,c)) ? a : c;
}
ユニットは明示的に宣言されていないことに注意してください。空間内のポイントを処理する場合、位置を決定するさまざまな方法があります。主なことは、ユニットを一貫したタイプに釘付けにする必要があるということです。
地球上の位置を操作するとき、私は主に緯度/経度の座標と大きさ/方向のベクトルを使用します。ベクトルと地球の位置に使用する既知のタイプがいくつかあります。それらの中には次のものがあります。
- 地球中心の地球固定(ECEF)座標系
- ノースイーストダウン(NED)
- 測地座標系
あなたの例として、私は測地学に固執することを検討するかもしれません。
これをまとめると、次のような擬似コードが作成される可能性があります。
Where a Vector is made up of Geodetic coordinates:
class Vector {
double x=0.0; //latitude
double y=0.0; //longitude
double h=0.0; //height
...
}
public Vector closestPoint(Vector lineStartA, Vector lineEndB, final Vector thePoint ) {
Vector w = thePoint.subtract(lineStartA);
double proj = w.dot(lineEndB);
// endpoint 0 is closest point
if ( proj <= 0.0f )
return lineStartA;
else
{
//Vector square
double vsq = lineEndB.dot(lineEndB);
// endpoint 1 is closest point
if ( proj >= vsq )
return lineStartA.add(lineEndB);
else
return lineStartA.add(lineEndB.multiply(proj/vsq));
}
}
double DistanceInKilometres(Vector lineStartA, Vector lineEndB, Vector thePoint) {
Vector cp=closestPoint(lineStartA, lineEndB, thePoint);
return getDistance(cp.x, cp.y, thePoint.x, thePoint.y);
}