从CGPoint到线段的最短距离

3
我一直在尝试将Douglas-Peucker算法实现到我的代码中,我能够将伪代码翻译成Swift,但最短距离函数shortestDistanceToSegment无法翻译。我找到的唯一Swift版本是在这里回答的,但我不明白它实际上是做什么。
我需要一个函数,将三个点作为参数(点和线段两端),并返回CGPoint和线段之间的最短距离。关于代码的解释(以及为什么)会很好,但不是必要的。

你从另一个SO答案引用的代码已经非常好文档化了,你到底不理解哪里呢? - Scott Hunter
所以你期望别人为你做这件事吗?试着自己动手做。 - martskins
@ScottHunter 我发现像 A、B、C、D、xx 和 yy 这样的变量名有些难以理解,所以我必须承认即使它能够工作,我也无法理解代码。 - Aleksi Sjöberg
@ lascort 我想看看它如何在Swift中完成,是的。并且也要解释一下。 - Aleksi Sjöberg
1个回答

15

来自https://dev59.com/fXRA5IYBdhLWcg3wuAcp#27737081的答案,重命名了变量并添加了一些注释:

/* Distance from a point (p1) to line l1 l2 */
func distanceFromPoint(p: CGPoint, toLineSegment v: CGPoint, and w: CGPoint) -> CGFloat {
    let pv_dx = p.x - v.x
    let pv_dy = p.y - v.y
    let wv_dx = w.x - v.x
    let wv_dy = w.y - v.y

    let dot = pv_dx * wv_dx + pv_dy * wv_dy
    let len_sq = wv_dx * wv_dx + wv_dy * wv_dy
    let param = dot / len_sq

    var int_x, int_y: CGFloat /* intersection of normal to vw that goes through p */

    if param < 0 || (v.x == w.x && v.y == w.y) {
        int_x = v.x
        int_y = v.y
    } else if param > 1 {
        int_x = w.x
        int_y = w.y
    } else {
        int_x = v.x + param * wv_dx
        int_y = v.y + param * wv_dy
    }

    /* Components of normal */
    let dx = p.x - int_x
    let dy = p.y - int_y

    return sqrt(dx * dx + dy * dy)
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接