### 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

## Leave a Reply