2010-03-31 25 views
2

J'ai un segment AB entre deux coordonnées WGS84 à la surface de la Terre (ou, alternativement, sur un ellipsoïde), et j'ai besoin de calculer la distance entre un point P et le point le plus proche de P sur le segment AB. Comment puis-je faire ceci?Calculez la distance entre un point et un segment de ligne sur un ellipsoïde (ou coordonnées WGS84)?

Toute aide est grandement appréciée.

Cordialement, Jochen

+0

Voir aussi [Comment calculer la distance entre un point et un segment de ligne, sur une sphère?] (Http://stackoverflow.com/questions/1299567/how-to-calculate-distance-from-a-point- to-a-line-segment-on-a-sphere). – tsauerwein

Répondre

1

J'ai jamais traité coordonnées WGS84 et je suis rouillé dans ce type de mathématiques, mais je vais vous donner ce qui est venu à l'esprit. Je ne réponds pas vraiment à cette question, mais c'était beaucoup trop pour mettre un commentaire, et il y a du code psudo. Je pensais juste que le problème était intéressant et je voulais un peu jouer avec. Quoi qu'il en soit, va ici ...

Imaginez l'ensemble de toutes les sphères dont le centre est P.

Maintenant, une seule de ces sphères de devrait partager exactement 1 point avec AB. Si vous avez une équation décrivant AB, alors vous devriez être capable de trouver la sphère centrée à ce partage exactement un point avec AB.

Il peut y avoir une façon plus rapide de faire cela que des essais et des erreurs, mais une recherche binaire est ce qui vient à l'esprit. Cela devrait trouver la distance en ligne droite à AB. Si vous voulez la disatance entre P et AB, je couvrirai ça après le 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 

Ce trouvera la distance en ligne droite entre P et AB en tant que le segment AB eliptical est plus proche de P que toute autre partie du Elipse que AB est sur. Si ce n'est pas vrai, il devrait être assez facile à tester pour cela et utilisez simplement le plus proche de A ou B comme point le plus proche. OK, donc vous vouliez réellement la distance de surface entre P et AB. C'est plus compliqué, mais vous pouvez probablement modifier mon algorithme pour fonctionner avec ça.