Find a line intersecting a known line at right ang

2020-02-26 10:23发布

This is basic graphics geometry and/or trig, and I feel dumb for asking it, but I can't remember how this goes. So:

  1. I have a line defined by two points (x1, y1) and (x2, y2).
  2. I have a third point (xp, yp) which lies somewhere else.

I want to compute the point (x', y') that lies somewhere along the line in #1, such that, when joined with the point from #2, creates a new perpendicular line to the first line. enter image description here

Thanks.

5条回答
老娘就宠你
2楼-- · 2020-02-26 10:42

The answer line is:

y=ax+b
where a=(x1-x2)/(y2-y1)
      b=yp-(x1-x2)*xp/(y2-y1)

How the result was obtained:

1) slope for the original line:   (y2-y1)/(x2-x1)

2) slope for the answer: -1/((y2-y1)/(x2-x1)) = (x1-x2)/(y2-y1)

3) Plug this into (xp,yp) we can have the result line.

Just calculate the answer from the lines after this (this is too long... I am hungry).

查看更多
Melony?
3楼-- · 2020-02-26 10:45

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.

查看更多
Ridiculous、
4楼-- · 2020-02-26 10:45

You can solve the slope of the line connecting (x1, y1) and (x2, y2). You then know the perpendicular line has a slope negative-inverse of that.

To find the y-intercept, use the slope to see how far the line travels in y from x=0 to x1.

b + (x1 - x0) * m = y1
b + (x1 -  0) * m = y1
b + (x1 * m)      = y1
b = y1 - x1 * m

You can then get the formulas for the line between your two points and the line from (xp, yp) with the above slope. For a given x, they have equal y's, so you can solve for that x, then plug that into either's formula for the y.

m = slope_from_1_to_2  = (y2 - y1) / (x2 - x1)
n = slopePerpendicular = (-1) / m

b = intercept_for_1_to_2 = y1 - x1 * m
c = intercept_for_p      = yp - xp * n

Thus the equations for the lines are of the form y = mx + b

Points 1 and 2:

y(x) = mx + b

Point p:

y(x) = nx + c

Set their y's equal to find x'

mx' + b = nx' + c
(m-n)x' = c - b
     x' = (c - b) / (m - n)

And thus use either formula to compute y'

y' = mx' + b

查看更多
干净又极端
5楼-- · 2020-02-26 10:56

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>

查看更多
Rolldiameter
6楼-- · 2020-02-26 11:01

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:

(qp) · r = λ (r · r)

And divide:

λ = (qp) · r / r · r

When you come to implement it, you need to check whether r · r = 0, to avoid division by zero.

查看更多
登录 后发表回答