{{ message }}

Instantly share code, notes, and snippets.

# wavebeem/snap point to line segment.md

Created Mar 31, 2021

# Snap Point To Line Segment

## Segment bisection cursor snapping

``````                                              +-------------+
|             |
|             |
|             |
|             |
|             |
+-------------+
XXXX
XXX        p2
XX
XX
+------------+XX
|            |
|            |
|            |
|            |
|            |
+------------+X
XXXX              XXX
XXXX       p4           XXX
XXX                         XX
+-----------+XX                             XXXX
|           |                                  XXXX  +------------+
|           |                                     XX |            |
|           |                                       X|            |
|           |                                        |            |
|           |                                        |            |
+-----------+                                        |            |
|            |
+------------+
p1
p3
``````

### Point definitions

p1 is the first node on the hovered segment.

p2 is the second node on the hovered segment.

p3 is the mouse cursor position.

p4 is the point we are trying to solve for.

### Other notes

p3 to p4 will form a perpendicular line to the p1 to p2 segment, because that is the shortest distance to the segment. A non perpendicular line would be longer, so we don't want that.

### Finding the point

We can think of this problem as finding the intersection of two line equations once we find the equations for the lines.

For the p1 to p2 segment we know both X, Y pairs so we can easily find the equation using point slope form:

``````y = m(x - p1.x) + p1.y
``````

Where `m` is the slope of the line defined by the "rise over run", which can be calculated as this fraction:

``````    p1.y - p2.y
m = -----------
p1.x - p2.x
``````

We also know that the slope of a perpendicular line is the negative reciprocal of the slope, meaning if the slope is `m`, the perpendicular line's slope is `-1 / m`.

So the p1 to p2 segment's equation is:

``````    p1.y - p2.y
y = ----------- * (x - p1.x) + p1.y
p1.x - p2.x
``````

To simplify writing the equation, we'll call the slope `m1` here:

``````y = m1 * (x - p1.x) + p1.y
``````

We only know one point on the perpendicular segment, but we can figure out the slope via `-1/m` formula, so that gives us:

``````         p1.x - p2.x
y = -1 * ----------- * (x - p3.x) + p3.y
p1.y - p2.y
``````

To simplify writing the equation, we'll call the slope `m2` here:

``````y = m2 * (x - p3.x) + p3.y
``````

In order to find where they intersect, we can set the two equations equal to each other and solve for X using algebra.

``````m1 * (x - p1.x) + p1.y = m2 * (x - p3.x) + p3.y
``````

Subtract `p1.y` from both sides:

``````m1 * (x - p1.x) = m2 * (x - p3.x) + p3.y - p1.y
``````

Distribute the multiplication of `m1` over the the subtraction:

``````(m1 * x) - (m1 * p1.x) = m2 * (x - p3.x) + p3.y - p1.y
``````

Distribute the multiplication of `m2` over the the subtraction:

``````(m1 * x) - (m1 * p1.x) = (m2 * x) - (m2 * p3.x) + p3.y - p1.y
``````

We want to get all the X on the left side, so we will subtact `(m2 * x)` from both sides:

``````(m1 * x) - (m1 * p1.x) - (m2 * x) = - (m2 * p3.x) + p3.y - p1.y
``````

We want to isolate the X's so we'll add the `(m1 * p1.x)` to both sides:

``````(m1 * x) - (m2 * x) = - (m2 * p3.x) + p3.y - p1.y + (m1 * p1.x)
``````

Now we can un-distribute the multiplication over the subtraction on the left:

``````(m1 - m2) * x = - (m2 * p3.x) + p3.y - p1.y + (m1 * p1.x)
``````

The final step is dividing by `m1 - m2`:

``````    -(m2 * p3.x) + p3.y - p1.y + (m1 * p1.x)
x = ----------------------------------------
(m1 - m2)
``````

So at this point, we know the equation solved for Y for the p3 to p4 segment, and we know an X value, so we plug in that X value to get the Y value, leaving us with the X, Y coordinate pair for p4.