2011-10-18 26 views

回答

2

谢谢你试图教我,但我已经要求一个简单实用的解决方案。不是数学leacture :)

不管怎么说,这是一个简单的答案:

看吧:http://www.movable-type.co.uk/scripts/latlong.html

计算“轴承”(从行开始从每个我想知道点的距离) +“串音距离”。

就是这样。我们完成了几行代码。没有迭代。没有附加的库。精益和意思

+1

我可以请你分享一些代码如何计算?我已经失去了大约一个星期尝试创建一个正常工作的东西。我会很感激。谢谢 – user007

-1

我没有使用lon/lat之前,但.. 我会创建一个坐标系。地心是原点。 转换成坐标系 的经度/纬度位置做你的计算 转换回经度/纬度

+1

除此之外,这并没有考虑到地球上的距离通常不是用直线来计算,而是作为在地球表面上延伸的弧线来计算的。 –

+0

此外,从大地测量(纬度/经度)转换到以地球为中心的地球固定(ECEF)很容易。从ECEF转换为大地测量不是。 – TreyA

7

我们将从做出一些假设:

所以,改写你的问题:

鉴于三根接地面点 - P0,P1和P2, 找到由p1和p2定义的大圆的小圆弧上的地球表面点,它与p0最接近。

至于解决的基础设施,我们需要:

  • 准确的函数,发现根据初始点,初始方位和距离目标点。
  • 精确的函数,用于测量两点之间的距离。

我建议分别使用GeographicLib的Direct和Inverse函数,这是我所知道的最准确的实现。

由于涉及到扁球体计算的数学非常非线性,我们将构建一个迭代解决方案。作为第一步,我们将尝试理解一个图表,其中X轴是由p1和p2定义的大圆的次弧上的一个点,而Y轴是从p0到那个的距离点 - 可能看起来像:

这样的图表可能看起来像几个选项:该函数可能是单调递增或单调递减。它可能还包含一个点,其一阶导数可能为0.它可能是最小值(相当平凡),但它也可能是最大值(例如 - 如果Lat(p0)= 0,Lat(p1)= 100和Lat(p2)= - 100)。但是,在所有情况下,导数都会改变符号的位置有0或1个点。

理解这一点,我们现在可以构建一个迭代算法。在每次迭代中:

我们将计算dist(p0,p1),dist(p0,p2)以及dist(p0,pM),其中M是p1和p2之间的中点,一个由p1和p2定义的大圆。现在。我们将检查:

  • 如果(DIST(P0,P1)< = DIST(P0,PM))& &(DIST(P0,PM)< = DIST(P0,P2)) - P0更接近对于p1比它到P2
  • 如果(DIST(P0,P2)< = DIST(P0,PM))& &(DIST(P0,PM)< = DIST(P0,P1)) - p 0为更接近P2比它要P1
  • 如果(DIST(P0,P1)= < DIST(P0,P2))& &(DIST(P0,P2)< = DIST(P0,PM)) - p 0为P1
  • 如果(DIST(P0,P2)< = DIST(P0,P1))& &(DIST(P0,P1)< = DIST(P0,PM)) - p 0为P2

否则,我们无法确定最小值是接近p1还是接近p2,因此我们将使用两个更多的点来检查:我们将pL定义为p1和pM之间的中点,pN为之间的中点pM和p2。现在,

  • 如果(DIST(P0,PL)< = DIST(P0,PM)) - p 0为更接近P1
  • 如果(DIST(P0,PN)< = DIST(P0,PM) ) - p0更接近p2

否则 - p0介于pL和pN之间。

因此,在每次迭代中,我们将正在寻找解决方案的弧长减半。

使用这种方法,我们可以在少于30次迭代中获得1厘米的精度。

4

我会用几何(而不是分析)方法详细说明Lior Kogan的优秀答案。

包含“线”的大圆位于通过球体中心的平面上。该平面与通过原点和分别为p1和p2的矢量的叉积得到的矢量正交。

现在,我们正在寻找与我们所在的平面正交的平面,并传递给p0。这可以很容易地计算出来,并且这个飞机与球体的交点应该是(警告:我有点匆忙,不知道这一步在数学上听起来像是)是与“线”正交的大圆, 。圆弧的交点应该是你正在寻找的点,并且可以计算为两个平面(与每个平面垂直的矢量的叉积)和球体共有的线的截取。

+0

一个快速的草图似乎证实,这应该产生正确的结果,无需迭代。 –

+0

我想在大地水准面与通过点和原点的矢量不正交的点上可能会出现一些问题。 –

-1

你有一条线穿过地表点A和B以及你想要计算距离的点C.

你可以计算三角形ABC的面积,由2

function computeDistanceToLine(p, line) { 
    var length = computeDistanceBetween(line.startPoint, line.endPoint); 
    var triangleArea = computeTriangleArea(p, line.startPoint, line.endPoint); 
    return 2 * triangleArea/length; 
} 

A和B之间通过的距离除以它,然后乘以用于两个点之间计算距离的算法是公知的。有很多的实现。其中一个(在以前的答案中可以发现)可以在那里找到http://www.movable-type.co.uk/scripts/latlong.html

对于计算三角形区域,您可以使用一些依赖于行长度的算法。例如

function computeTriangleArea(p0, p1, p2) { 
    var r = 6378137; 

    var d0 = computeDistanceBetween(p0, p1); 
    var d1 = computeDistanceBetween(p1, p2); 
    var d2 = computeDistanceBetween(p2, p0); 

    var halfPerimeter = (d0 + d1 + d2) * 0.5; 

    var t = Math.tan(halfPerimeter) * 
     Math.tan((halfPerimeter - d0) * 0.5) * 
     Math.tan((halfPerimeter - d1) * 0.5) * 
     Math.tan((halfPerimeter - d2) * 0.5); 

    return 4 * Math.atan(Math.sqrt(Math.abs(t))) * r * r; 
} 
-1

伊利亚Golota的答案是正确的做法,但原来它总是返回一个非常大的数字,例如“3.0355243098445522e12”即使是远离线2米点。我这样做是为了计算三角形面积,而不是:(采用海伦公式)

double d0 = computeDistanceBetween(p0, p1); 
double d1 = computeDistanceBetween(p1, p2); 
double d2 = computeDistanceBetween(p2, p0); 

double area = Math.sqrt(halfP*(halfP-d0)*(halfP-d1)*(halfP-d2)); 

再插上这里的面积值

double distanceToLine = 2*area/computeDistanceBetween(line.startPoint, line.endPoint) 

这很适合我和以米为单位返回从点到线的垂直距离。