计算椭圆体(或WGS84坐标)上的点和线段之间的距离?

发布于 2024-08-27 07:06:46 字数 117 浏览 7 评论 0原文

我在地球表面(或者在椭球体上)的两个 WGS84 坐标之间有一条线段 AB,并且需要计算点 P 与线段 AB 上距离 P 最近的点之间的距离。我该怎么做?

非常感谢任何帮助。

问候, 约亨

I have a line segment AB between two WGS84 coordinates on the earth's surface (or, alternatively, on an ellipsoid), and need to calculate the distance between a point P and the point nearest to P that is on line segment AB. How can I do this?

Any help is greatly appreciated.

Regards,
Jochen

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

因为看清所以看轻 2024-09-03 07:06:46

我从来没有处理过 WGS84 坐标,对这种类型的数学也很生疏,但我会告诉你我想到的。我并没有真正回答这个问题,但这太多了,无法发表评论,而且它有伪代码。我只是觉得这个问题很有趣,想尝试一下。无论如何,这里...

想象一下以 P 为中心的所有球体的集合。

现在,这些球体中只有一个应该与 AB 恰好共享 1 个点。如果你有一个描述 AB 的方程,那么你应该能够找到以与 AB 恰好共享一个点为中心的球体。

可能有比反复试验更快的方法来做到这一点,但我想到的是二分搜索。这应该找到到 AB 的直线距离。如果你想要 P 和 AB 之间的距离,我会在代码后面介绍。
psudocode:

   Radius_lo = 0
   Radius_hi = minimum( distance(P, A), distance(P, B) )
   Radius_test = Raduis_hi // you may want to add a miniscule amount to this to keep from floating point inprecision from effectively rounding down which could lead to no actual intersection
   while true
      intersections = intersection_points( sphere( P, Radius_test), AB )
      if ( count(intersections) == 1 ) // or close enough.  With floating pt math you'll likely need to recognize close enough or it will never exit.
            return  Radius_test
      if ( count(intersections) == 2 )
            // Here you may do one of two things, both of which are binary searches.
            // 1. The first and simplest would be to divide average _test with _lo and try again
            Radius_hi = Radius_test
            Radius_test = (Radius_test + Radius_lo) / 2
            Continue
            // 2. The second would be to attempt to divide the segment fromed by the two intersection points, which is more complicated, but would almost always result in fewer times through the loop
            X = midpoint(intersection[0], intersection[1]) // midpoint would have to know how to find the midpoint of them along the elipse that they live on
            Radius_test = distance( P, X)
            Continue
     if ( count(intersections) == 0)
           // Gone too far.  If you had done (1) above, then do
           Radius_lo = Radius_test
           Radius_test = (Radius_test + Radius_hi) / 2
           Continue
           // If on the otherhand you had done (2) above then you shouldn't ever have this case
           error("0 intersections!")
     // Now, this should be for any intersection count other than 0, 1, or 2.  This shouldn't happen so
     error("bad intersection count")
  endloop // while true

只要椭圆线段 AB 比 AB 所在椭圆的任何其他部分更靠近 P,就可以找到 P 和 AB 之间的直线距离。如果这不是真的,那么测试这一点应该很容易,只需使用 A 或 B 中较接近的点作为最近的点即可。

好的,所以您实际上想要 P 和 AB 之间的表面距离。这更复杂,但你可以改变我的算法来处理它。

I've never dealt with WGS84 coordinates and am rusty in this type of math, but I'll give you what came to mind. I'm not really answering this question, but this was way too much to put in a comment, and it has psudo code. I just thought that the problem was interesting and wanted to play around with it a little bit. Anyway, here goes...

Imagine the set of all spheres whose center is P.

Now, only one of those sphere's should share exactly 1 point with AB. If you have an equation describing AB then you should be able to find the sphere centered at that shares exactly one point with AB.

There may be a swifter way to do this than trial and error, but a binary search is what comes to mind. This should find the straight line distance to AB. If you want the disatance between P and AB I'll sorta cover that after the code.
psudocode:

   Radius_lo = 0
   Radius_hi = minimum( distance(P, A), distance(P, B) )
   Radius_test = Raduis_hi // you may want to add a miniscule amount to this to keep from floating point inprecision from effectively rounding down which could lead to no actual intersection
   while true
      intersections = intersection_points( sphere( P, Radius_test), AB )
      if ( count(intersections) == 1 ) // or close enough.  With floating pt math you'll likely need to recognize close enough or it will never exit.
            return  Radius_test
      if ( count(intersections) == 2 )
            // Here you may do one of two things, both of which are binary searches.
            // 1. The first and simplest would be to divide average _test with _lo and try again
            Radius_hi = Radius_test
            Radius_test = (Radius_test + Radius_lo) / 2
            Continue
            // 2. The second would be to attempt to divide the segment fromed by the two intersection points, which is more complicated, but would almost always result in fewer times through the loop
            X = midpoint(intersection[0], intersection[1]) // midpoint would have to know how to find the midpoint of them along the elipse that they live on
            Radius_test = distance( P, X)
            Continue
     if ( count(intersections) == 0)
           // Gone too far.  If you had done (1) above, then do
           Radius_lo = Radius_test
           Radius_test = (Radius_test + Radius_hi) / 2
           Continue
           // If on the otherhand you had done (2) above then you shouldn't ever have this case
           error("0 intersections!")
     // Now, this should be for any intersection count other than 0, 1, or 2.  This shouldn't happen so
     error("bad intersection count")
  endloop // while true

This will find the straight line distance between P and AB as long as the eliptical segment AB is closer to P than any other part of the elipse that AB lies on. If this isn't true it should be easy enough to test for that and just use the closer of A or B as the closest point.

Ok, so you actually wanted the surface distance between P and AB. This is more complicated, but you can likely alter my algorithm to work with that.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文