右動作しない大円機能を点からラインまでの距離。
-
20-08-2019 - |
質問
私はラインに緯度/経度点からの距離を取得する必要があります。もちろん、グレートサークルを追跡する必要があります。
//www.movable:私は HTTPでこの上の素晴らしい記事を見つけました-type.co.uk/scripts/latlong.htmlする
が、コードが正しく動作しません。どちらか私が何か間違ったことをやっているか、不足している何かがあります。ここで問題になっている機能です。必要に応じて他の機能のためのリンクを参照してください。
var R = 3961.3
LatLon.crossTrack = function(lat1, lon1, lat2, lon2, lat3, lon3) {
var d13 = LatLon.distHaversine(lat1, lon1, lat3, lon3);
var brng12 = LatLon.bearing(lat1, lon1, lat2, lon2);
var brng13 = LatLon.bearing(lat1, lon1, lat3, lon3);
var dXt = Math.asin(Math.sin(d13/R)*Math.sin(brng13-brng12)) * R;
return dXt;
}
緯度/ lon1 = -94.127592、41.81762
緯度/ lon2 = -94.087257、41.848202
緯度/ lon3 = -94.046875、41.791057
これは、0.865マイルを報告します。実際の距離は4.29905マイルです。
この問題を解決する方法についてどのような手掛かり?私は数学者ではないよ、歯のプログラマでちょうど長います。
解決
ほとんどの三角関数はラジアンを必要としています。度での角度の対策はありますか?おそらく彼らは、通常の式を使用して変換する必要があります:
2 *πラジアン= 360°
あなたは半正矢の式の計算式の下で見ると、あなたがこれを参照してくださいよ。
(角度機能をトリグに渡すラジアンにする必要があることに注意してください)。
他のヒント
これらの座標に同じ値を返すあなたの機能であります:
crossTrack(0,0,0,1,0.1,0.5);
crossTrack(0,0,0,1,0.1,0.6);
crossTrack(0,0,0,1,0.1,0.4);
私はそれが必要だと思うが、鉱山にはありません。第3点は、常に、赤道から北に0.1です。結果に影響を及ぼしてはならないだけ経度変化。それはそれがないと思われる通ります。
私はaalatlonなど、それを送るこのpointlinedistancetestを試してみました。
private static final double _eQuatorialEarthRadius = 6378.1370D;
private static final double _d2r = (Math.PI / 180D);
private static double PRECISION = 1;
// Haversine Algorithm
// source: http://stackoverflow.com/questions/365826/calculate-distance-between-2-gps-coordinates
private static double HaversineInM(double lat1, double long1, double lat2, double long2) {
return (1000D * HaversineInKM(lat1, long1, lat2, long2));
}
private static double HaversineInKM(double lat1, double long1, double lat2, double long2) {
double dlong = (long2 - long1) * _d2r;
double dlat = (lat2 - lat1) * _d2r;
double a = Math.pow(Math.sin(dlat / 2D), 2D) + Math.cos(lat1 * _d2r) * Math.cos(lat2 * _d2r)
* Math.pow(Math.sin(dlong / 2D), 2D);
double c = 2D * Math.atan2(Math.sqrt(a), Math.sqrt(1D - a));
double d = _eQuatorialEarthRadius * c;
return d;
}
// Distance between a point and a line
public static double pointLineDistanceTest(double[] aalatlng,double[] bblatlng,double[]cclatlng){
double [] a = aalatlng;
double [] b = bblatlng;
double [] c = cclatlng;
double[] nearestNode = nearestPointGreatCircle(a, b, c);
// System.out.println("nearest node: " + Double.toString(nearestNode[0])
+ ","+Double.toString(nearestNode[1]));
double result = HaversineInM(c[0], c[1], nearestNode[0], nearestNode[1]);
// System.out.println("result: " + Double.toString(result));
return (result);
}
// source: http://stackoverflow.com/questions/1299567/how-to-calculate-distance-from-a-point-to-a-line-segment-on-a-sphere
private static double[] nearestPointGreatCircle(double[] a, double[] b, double c[])
{
double[] a_ = toCartsian(a);
double[] b_ = toCartsian(b);
double[] c_ = toCartsian(c);
double[] G = vectorProduct(a_, b_);
double[] F = vectorProduct(c_, G);
double[] t = vectorProduct(G, F);
return fromCartsian(multiplyByScalar(normalize(t), _eQuatorialEarthRadius));
}
@SuppressWarnings("unused")
private static double[] nearestPointSegment (double[] a, double[] b, double[] c)
{
double[] t= nearestPointGreatCircle(a,b,c);
if (onSegment(a,b,t))
return t;
return (HaversineInKM(a[0], a[1], c[0], c[1]) < HaversineInKM(b[0], b[1], c[0], c[1])) ? a : b;
}
private static boolean onSegment (double[] a, double[] b, double[] t)
{
// should be return distance(a,t)+distance(b,t)==distance(a,b),
// but due to rounding errors, we use:
return Math.abs(HaversineInKM(a[0], a[1], b[0], b[1])-HaversineInKM(a[0], a[1], t[0], t[1])-HaversineInKM(b[0], b[1], t[0], t[1])) < PRECISION;
}
// source: http://stackoverflow.com/questions/1185408/converting-from-longitude-latitude-to-cartesian-coordinates
private static double[] toCartsian(double[] coord) {
double[] result = new double[3];
result[0] = _eQuatorialEarthRadius * Math.cos(Math.toRadians(coord[0])) * Math.cos(Math.toRadians(coord[1]));
result[1] = _eQuatorialEarthRadius * Math.cos(Math.toRadians(coord[0])) * Math.sin(Math.toRadians(coord[1]));
result[2] = _eQuatorialEarthRadius * Math.sin(Math.toRadians(coord[0]));
return result;
}
private static double[] fromCartsian(double[] coord){
double[] result = new double[2];
result[0] = Math.toDegrees(Math.asin(coord[2] / _eQuatorialEarthRadius));
result[1] = Math.toDegrees(Math.atan2(coord[1], coord[0]));
return result;
}
// Basic functions
private static double[] vectorProduct (double[] a, double[] b){
double[] result = new double[3];
result[0] = a[1] * b[2] - a[2] * b[1];
result[1] = a[2] * b[0] - a[0] * b[2];
result[2] = a[0] * b[1] - a[1] * b[0];
return result;
}
private static double[] normalize(double[] t) {
double length = Math.sqrt((t[0] * t[0]) + (t[1] * t[1]) + (t[2] * t[2]));
double[] result = new double[3];
result[0] = t[0]/length;
result[1] = t[1]/length;
result[2] = t[2]/length;
return result;
}
private static double[] multiplyByScalar(double[] normalize, double k) {
double[] result = new double[3];
result[0] = normalize[0]*k;
result[1] = normalize[1]*k;
result[2] = normalize[2]*k;
return result;
}
所属していません StackOverflow