Find a line intersecting a known line at right angle, given a point
To all those poor souls looking for a concrete example using vectors... here I build upon Gareth's answer.
You have a vector from p to r (from 0,0 to 50,-50) and another point, q, which is at (50, 0). The right-angle intersection of q and the vector from p to r is { x: 25. y: -25 } and is derived with the following code.
const p = [0, 0];
const r = [50, -50];
const q = [50, 0];
const l = math.add(p, r);
const m = math.dot(math.subtract(q, p), r) / math.dot(r, r);
console.log('intersecting point', math.multiply(l, m));
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjs/5.1.2/math.js"></script>
You can find that point by considering first a generic point (x, y)
along the line from (x1, y1)
to (x2, y2)
:
x = x1 + t*(x2 - x1)
y = y1 + t*(y2 - y1)
and the computing the (squared) distance from this point from (xp, yp)
E = (x - xp)**2 + (y - yp)**2
that substituting the definition of x
and y
gives
E = (x1 + t*(x2 - x1) - xp)**2 +
(y1 + t*(y2 - y1) - yp)**2
then to find the minimum of this distance varying t
we derive E
with respect to t
dE/dt = 2*(x1 + t*(x2 - x1) - xp)*(x2 - x1) +
2*(y1 + t*(y2 - y1) - yp)*(y2 - y1)
that after some computation gives
dE/dt = 2*((x1 - xp)*(x2 - x1) + (y1 - yp)*(y2 - y1) +
t*((x2 - x1)**2 + (y1 - y2)**2))
looking for when this derivative is zero we get an explicit equation for t
t = ((xp - x1)*(x2 - x1) + (yp - y1)*(y2 - y1)) /
((x2 - x1)**2 + (y2 - y1)**2)
so the final point can be computed using that value for t
in the definition of (x, y)
.
Using vector notation this is exactly the same formula suggested by Gareth...
t = <p - p1, p2 - p1> / <p2 - p1, p2 - p1>
where the notation <a, b>
represents the dot product operation ax*bx + ay*by
.
Note also that the very same formula works in an n-dimensional space.
A useful rule of thumb in this kind of computational geometry is that you should work with vectors as long as you can, switching to Cartesian coordinates only as a last resort. So let's solve this using vector algebra. Suppose your line goes from p to p + r, and the other point is q.
Now, any point on the line, including the point you are trying to find (call it s), can be expressed as s = p + λ r for a scalar parameter λ.
Now the vector from q to s must be perpendicular to r. Therefore
(q − (p + λ r)) · r = 0
Where · is the dot product operator. Expand the product:
(q − p) · r = λ (r · r)
And divide:
λ = (q − p) · r / r · r
When you come to implement it, you need to check whether r · r = 0, to avoid division by zero.