3d 点到多段线段的距离算法

发布于 2024-10-15 01:21:05 字数 306 浏览 1 评论 0原文

我有一条路径,由 n 个 3d 坐标组成,全部串联连接,可以在 此图

我想找到我的点和多段线段之间的最短距离。我可以计算一个点到一条线段的距离,但我想为更复杂的路径执行此操作。

是否有一种算法不依赖于测试每个线段到点的距离并存储最小值?任何指向正确方向的指针都会很棒!

这是一个游戏项目,我想计算玩家与游戏中存在的河流的距离。河流将用多段线段表示。

谢谢

I have a path, made up of n 3d coordinates, all connected in series, which can be seen in this diagram.

I want to find the shortest distance between my point and the poly line segment. I can calculate the distance of a point from a single line segment, but I want to do it for a more complicated path.

Is there an algorithm for this that does not rely on testing every line segment to point distance and stores the minimum? Any pointers in the right direction would be great!

This is for a games project where I want to calculate the distance of the player from a river that exists in the game. The river will be represented with poly line segments.

Thanks

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

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

发布评论

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

评论(1

谈情不如逗狗 2024-10-22 01:21:05
/**
 * Calculates the euclidean distance from a point to a line segmented path.
 *
 * @param v     the point from with the distance is measured
 * @param path  the array of points wich, when sequentialy joined by line segments, form a path
 * @return      distance from v to closest of the path forming line segments
 *
 * @author      Afonso Santos
 */
public static
double
distanceToPath( final R3 v, final R3[] path )
{
    double minDistance = Double.MAX_VALUE ;

    for (int pathPointIdx = 1  ;  pathPointIdx < path.length  ;  ++pathPointIdx)
    {
        final double d = distanceToSegment( v, path[pathPointIdx-1], path[pathPointIdx] ) ;

        if (d < minDistance)
            minDistance = d ;
    }

    return minDistance;
}


/**
 * Calculates the euclidean distance from a point to a line segment.
 *
 * @param v     the point
 * @param a     start of line segment
 * @param b     end of line segment
 * @return      distance from v to line segment [a,b]
 *
 * @author      Afonso Santos
 */
public static
double
distanceToSegment( final R3 v, final R3 a, final R3 b )
{
    final R3 ab = b.sub( a ) ;
    final R3 av = v.sub( a ) ;

    if (av.dot(ab) <= 0.0)              // Point is lagging behind start of the segment, so perpendicular distance is not viable.
        return av.modulus( ) ;          // Use distance to start of segment instead.

    final R3 bv = v.sub( b ) ;

    if (bv.dot(ab) >= 0.0)              // Point is advanced past the end of the segment, so perpendicular distance is not viable.
        return bv.modulus( ) ;          // Use distance to end of the segment instead.

    // Point is within the line segment's start/finish boundaries, so perpendicular distance is viable.
    return (ab.cross( av )).modulus() / ab.modulus() ;      // Perpendicular distance of point to segment.
}

R3 3D 矢量代数 java 包的其余部分(自包含,无外​​部依赖项)位于此处:
https://gist.github.com/reciprocum/4e3599a9563ec83ba2a63f5a6cdd39eb

开源库的一部分
https://sourceforge.net/projects/geokarambola/

/**
 * Calculates the euclidean distance from a point to a line segmented path.
 *
 * @param v     the point from with the distance is measured
 * @param path  the array of points wich, when sequentialy joined by line segments, form a path
 * @return      distance from v to closest of the path forming line segments
 *
 * @author      Afonso Santos
 */
public static
double
distanceToPath( final R3 v, final R3[] path )
{
    double minDistance = Double.MAX_VALUE ;

    for (int pathPointIdx = 1  ;  pathPointIdx < path.length  ;  ++pathPointIdx)
    {
        final double d = distanceToSegment( v, path[pathPointIdx-1], path[pathPointIdx] ) ;

        if (d < minDistance)
            minDistance = d ;
    }

    return minDistance;
}


/**
 * Calculates the euclidean distance from a point to a line segment.
 *
 * @param v     the point
 * @param a     start of line segment
 * @param b     end of line segment
 * @return      distance from v to line segment [a,b]
 *
 * @author      Afonso Santos
 */
public static
double
distanceToSegment( final R3 v, final R3 a, final R3 b )
{
    final R3 ab = b.sub( a ) ;
    final R3 av = v.sub( a ) ;

    if (av.dot(ab) <= 0.0)              // Point is lagging behind start of the segment, so perpendicular distance is not viable.
        return av.modulus( ) ;          // Use distance to start of segment instead.

    final R3 bv = v.sub( b ) ;

    if (bv.dot(ab) >= 0.0)              // Point is advanced past the end of the segment, so perpendicular distance is not viable.
        return bv.modulus( ) ;          // Use distance to end of the segment instead.

    // Point is within the line segment's start/finish boundaries, so perpendicular distance is viable.
    return (ab.cross( av )).modulus() / ab.modulus() ;      // Perpendicular distance of point to segment.
}

The rest of the (self contained, no external dependencies) R3 3D vector algebra java package is here:
https://gist.github.com/reciprocum/4e3599a9563ec83ba2a63f5a6cdd39eb

part of the open source library
https://sourceforge.net/projects/geokarambola/

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