我一直在寻找一段时间,但我找不到我正在寻找的东西。
我正在开发一款可以进入赛车的应用。它将使驾驶员能够按下按钮来标记开始/结束线。它还有一个按钮,允许驱动程序设置段时间。
请记住,轨道可以是我首先处理的椭圆形。它可以是道路路线,也可以是自动十字路口,起点和终点线不是完全相同的位置。它们可能相距50英尺左右,但汽车从未穿过它开始的地方。
我有我的gps数据,我将NMea消息转换为我的课程,我存储了Lat,Lon,Speed,Course等。在我的研究中,我遇到过这个有趣的事情。 GPS将安装在屋顶外,以获得更好的信号。它每秒产生10次点击。 (Garmin Glo)
http://www.drdobbs.com/windows/gps-programming-net/184405690?pgno=1
它已经陈旧但它谈到了UTM和笛卡尔坐标系。所以使用DecDeg2UTM,我转换Lat& Lon to X&也是坐标。
我也一直试图使用我找到的相交公式Here我拿了相交并尝试将其转换为C#,我将在最后发布。但是,输入椭圆形轨道的坐标,它似乎并没有起作用。而且,我不确定它应该做什么。但是当它像-35.xxx& 98.xxxx出自距离赛道1000英里的海洋。
我正在寻找以下答案。
同样,如果有一个GIS库,那么我可以提供坐标并计算所有这些,只要它具有高效性,它就会起作用。如果不是这样的话,我会尝试决定是否最好将坐标分解为X Y或几何公式为十进制格式的坐标。 Mods,我认为有硬数据支持任何一种方式的答案,这不是对意见完全主观的反应。
这是我从上面的脚本页面中提出的C#代码。我开始感觉到UTM,而笛卡尔坐标系统对于准确性和性能会更好。但是,如果它存在,我还可以接受相反的证据。
由于
P.S。注意GeoCoordinate来自.Net System.Device.Location汇编。 GpsData只是我用来将NMEA消息转换为Lat,Lon,Course,NumSats,DateTime等的类。
Radian方法的扩展如下:
public static double DegreeToRadians(this double angle)
{
return Math.PI * angle / 180.0;
}
public static double RadianToDegree(this double angle)
{
return angle * (180.0 / Math.PI);
}
}
public static GeoCoordinate CalculateIntersection(GpsData p1, double brng1, GpsData p2, double brng2)
{
// see http://williams.best.vwh.net/avform.htm#Intersection
// Not sure I need to use Cosine
double _p1LatRadians = p1.Latitude.DegreeToRadians();
double _p1LonToRadians = p1.Longitude.DegreeToRadians();
double _p2LatToRadians = p2.Latitude.DegreeToRadians();
double _p2LonToRadians = p2.Longitude.DegreeToRadians();
double _brng1ToRadians = brng1.DegreeToRadians();
double _brng2ToRadians = brng2.DegreeToRadians();
double _deltaLat = _p2LatToRadians - _p1LatRadians;
double _deltaLon = _p2LonToRadians - _p1LonToRadians;
var _var1 = 2 * Math.Asin(Math.Sqrt(Math.Sin(_deltaLat / 2) * Math.Sin(_deltaLat / 2)
+ Math.Cos(_p1LatRadians) * Math.Cos(_p2LatToRadians) * Math.Sin(_deltaLon / 2) * Math.Sin(_deltaLon / 2)));
if (_var1 == 0) return null;
// initial/final bearings between points
var _finalBrng = Math.Acos((Math.Sin(_p2LatToRadians) - Math.Sin(_p1LatRadians) * Math.Cos(_var1)) / (Math.Sin(_var1) * Math.Cos(_p1LatRadians)));
//if (isNaN(θa)) θa = 0; // protect against rounding
var θb = Math.Acos((Math.Sin(_p1LatRadians) - Math.Sin(_p2LatToRadians) * Math.Cos(_var1)) / (Math.Sin(_var1) * Math.Cos(_p2LatToRadians)));
var θ12 = Math.Sin(_p2LonToRadians - _p1LonToRadians) > 0 ? _finalBrng : 2 * Math.PI - _finalBrng;
var θ21 = Math.Sin(_p2LonToRadians - _p1LonToRadians) > 0 ? 2 * Math.PI - θb : θb;
var α1 = (_brng1ToRadians - θ12 + Math.PI) % (2 * Math.PI) - Math.PI; // angle 2-1-3
var α2 = (θ21 - _brng2ToRadians + Math.PI) % (2 * Math.PI) - Math.PI; // angle 1-2-3
if (Math.Sin(α1) == 0 && Math.Sin(α2) == 0) return null; // infinite intersections
if (Math.Sin(α1) * Math.Sin(α2) < 0) return null; // ambiguous intersection
α1 = Math.Abs(α1);
α2 = Math.Abs(α2);
// ... Ed Williams takes abs of α1/α2, but seems to break calculation?
var α3 = Math.Acos(-Math.Cos(α1) * Math.Cos(α2) + Math.Sin(α1) * Math.Sin(α2) * Math.Cos(_var1));
var δ13 = Math.Atan2(Math.Sin(_var1) * Math.Sin(α1) * Math.Sin(α2), Math.Cos(α2) + Math.Cos(α1) * Math.Cos(α3));
var _finalLatRadians = Math.Asin(Math.Sin(_p1LatRadians) * Math.Cos(δ13) + Math.Cos(_p1LatRadians) * Math.Sin(δ13) * Math.Cos(_brng1ToRadians));
var _lonBearing = Math.Atan2(Math.Sin(_brng1ToRadians) * Math.Sin(δ13) * Math.Cos(_p1LatRadians), Math.Cos(δ13) - Math.Sin(_p1LatRadians) * Math.Sin(_finalLatRadians));
var _finalLon = _p1LonToRadians + _lonBearing;
var _returnLat = _finalLatRadians.RadianToDegree();
var _latToDegree = _finalLon.RadianToDegree();
var _returnLon = ( _latToDegree + 540) % 360 - 180;
return new GeoCoordinate(_returnLat, _returnLon);
//return new LatLon(φ3.toDegrees(), (λ3.toDegrees() + 540) % 360 - 180); // normalise to −180..+180°
}