3

I've been trying to implement Douglas-Peucker algorithm into my code and I'm able to translate pseudocode into Swift, except for the shortestDistanceToSegment function. Only Swift version I could find was answered here but I don't understand what that actually does.

I need a function that gets three points as arguments (point and both ends of line) and returns the shortest distance between a CGPoint and a line segment. Some explanation about what (and why) the code does would great but not necessary.

Community
  • 1
  • 1
Aleksi Sjöberg
  • 1,454
  • 1
  • 12
  • 34

1 Answers1

15

Answer from https://stackoverflow.com/a/27737081/535275 w/ variables renamed & some comments added:

/* 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)
}
Community
  • 1
  • 1
Scott Hunter
  • 48,888
  • 12
  • 60
  • 101