Snapping a Point to a Line Segment

Following up yesterday’s post on hit-testing a point within a polygon, there’s one other key geometric function that the Lassie engine’s motion grid would required in order to support polygonal motion areas: that’s the ability to snap stray (out-of-grid) clicks onto grid lines.

This took a bit of digging around to get working correctly… specifically, I wanted the point to snap to a line segment, therefore the snapped point’s position needs to be limited by the extent of the segment’s two end points. Ultimately, the operation turned out to be pretty compact:

// Snaps point P to the nearest position along line segment AB.
// @param p: The point to snap.
// @param a: First point of the line segment.
// @param b: Second point of the line segment.
// @return: A new point object with "x" and "y" coordinates.
function snapPointToLine(p, a, b) {
    var ap1 = p.x-a.x,
        ap2 = p.y-a.y,
        ab1 = b.x-a.x,
        ab2 = b.y-a.y,
        mag = ab1*ab1 + ab2*ab2,
        dot = ap1*ab1 + ap2*ab2,
        t = dot/mag;

    if (t < 0) {
        return {x: a.x, y: a.y};
    } else if (t > 1) {
        return {x: b.x, y: b.y};
    } else {
        return {x: a.x+ab1*t, y: a.y+ab2*t};
    }
}

Give it a try:

var a = {x:0, y:0};
var b = {x:50, y:50};
snapPointToLine({x:0, y:50}, a, b); // {x: 25, y: 25}
snapPointToLine({x:100, y:100}, a, b); // {x: 50, y: 50}
Advertisements

No comments yet

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: