Finding normal of arbitrary line.

This topic is 4884 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

Hi. I'm wondering how you find the normal (perpendicular line) of a line from (x1, y1) to (x2, y2). I think this question was answered before somewhere but the answer made use of a Vector2D object. I want to know the actual math behind it. Thank you.

Share on other sites
Find the vector from point 1 to point 2 (x2-x1, y2-y1) = (dx, dy)

The normal is (-dy, dx) or (dy, -dx), depending on direction.

Share on other sites
Uhh.. the obvious one is (0,0,1) since we are talking about a 2D plane.

:D

Share on other sites
When you say the normal is "(-dy, dx) or (dy, -dx), depending on direction," you mean it depends on which side of the line you put the normal, right?

Also, what does "the obvious one is (0,0,1) since we are talking about a 2D plane" mean?

My additional problem is figuring out which side to put the normal on. You see, this is for collision detection between a moving point or circle and a stationary line (I want the time of contact). So, I want a way to know which side of the line the point is so I know where to put my line's normal.

Share on other sites
I'm just totally thinking this up off the top of my head, but maybe try this:

Compare the circle's position with the position of the highest endpoint of the line (on the y-axis). If the points (circle.x - circle.radius, circle.y) and (circle.x + circle.radius, circle.y) are both to the right of highest endpoint, then so the circle is to the line. Vice versa with left. Don't hold me on this though [smile]

<edit>
It seems what I said is only true of segments with negative slope. For positvely sloped segments, compare against the lowest endpoint.
</edit>

Share on other sites
A normal is just the line perpendicular to the line. So there are TWO normals. For instance, if the line is from (1,1) to (5, 1) there is a normal facing left and a normal facing right.

What the first AP was doing was just 'rotating' the line 90 degrees... But the question is which direction do you want to rotate?

Share on other sites
Quote:
 You see, this is for collision detection between a moving point or circle and a stationary line (I want the time of contact). So, I want a way to know which side of the line the point is so I know where to put my line's normal.
If your line normal is unit-length, intersecting a moving point or circle with the line is pretty easy; it's the same formula as intersecting a line and a plane in 3d (easy to find with google). To find the first time of contact with a moving circle, you simply offset the plane distance by the circle radius. (Maybe you already knew all that...)

If you mean a line segment rather than an infinite line, that adds a little complexity in that you may have to sweep the circle against the segment endpoints as well, which involves solving a quadratic equation.

As for which way the normal points, that's up to you. Assuming the x axis is to the right and the y axis is up, [-y, x] is 90 degrees CCW from the line direction and [y, -x] is 90 degrees CW. It's also up to you whether the line is 'two-sided', or whether intersections on the 'back side' are culled.

Share on other sites
O.K. I finally figured out how do get the normal in the direction I want.

I have a line that goes from (Lx1, Ly1) to (Lx2, Ly2), as well as a point at (Px, Py).

I find the vector of the line; the vector from (Lx1, Ly1) to (Lx2, Ly2). I call it dL:

dLx = Lx2 - Lx1
dLy = Ly2 - Ly1

I find dL's magnitude with Pythagoras, then I get its normal vector nL:

nLx = dLx / dL
nLy = dLy / dL

Next I find the vector from the ship to the line's start point; (Px, Py) to (Lx1, Ly1). I call this dPL:

dPLx = Px - Lx1
dPLy = Py - Ly1

Now I find the dot product of nL and dPL:

dotprod = dotprod = (dPLx * nLx) + (dPLy * nLy)

dotprod is the magnitude of the component of dPL parallel to dL, which forms a right triangle along with the dPL vector and the line's normal extended to the point.

** If I'm just working with a segment, I can test if dotprod is the same length as or longer than the line. If it is, then the shortest distance between the point and the line segment is actually the line between the point and the line's end-point (Lx2, Ly2). I have yet to figure out when the shortest distance is actually between the point and (Lx1, Ly1) though. **

** UPDATE
The shortest distance is just between the point and (Lx1, Ly1) when the dot product is equal to or less than 0. **

To find the normal I multiply nL by dotprod to get the vector components parallel to the line:

dNx = (Lx1 + (nLx * dotprod)) - Px
dNy = (Ly1 + (nLy * dotprod)) - Py

So, a line drawn between (Px, Py) and (Px + dNx, Py + dNy) would be the shortest line you could draw between the point and the line extended to infinity.

For circles, you normalize dN (I'll call it nN) then multiply it by the circle's radius. The intersection point is (Px + (nNx * radius), Py + (nNy * radius)).

UPDATE
I think I found a better algorithm at <http://www.c-program.com/c-g-a-faq1.html#Geometry2D>, though I don't know if it deals with line segments or not. Look under "How do I find the distance from a point to a line?" I don't know what they mean by "L**2" though. It's probably L squared.

[Edited by - Zaxx on June 4, 2005 9:17:20 AM]

Share on other sites
The easy way is to use a dot product.

If you have the vector (x, y) = (x2-x1, y2-y1) and you want to find its "normal" vector, (a, b), state first that (x, y) * (a, b) = 0.

Therefore ax + by = 0.

Then, choose any non-zero value for a, solve for b. All solutions for (a, b) will be parallel, so you can choose any one you want.

Example: Finding the normal of (1, 2):

(x, y) = (1, 2)
(x, y) dot (a, b) = 0
a + 2b = 0

So, if a = 2, b = -1, if a = -4, b = 2, and (-4, 2) = -2 * (2, -1), showing that these two solutions are parallel.

The quick way to solve something like this mentally is to use the slope.
Let m1 = y / x. m2 = -x/y.

Here's why:

(x, y) dot (-y, -x)
= -xy + xy
= 0

So the quick way is to use the negative reciprocal of the slope. Position of the line in the parametric form (u, v) + d(a, b) for d spanning the real numbers will be perpendicular to (x, y) for any point (u, v). This means your result will be y = b/a * x + c for any real number c.

1. 1
Rutin
32
2. 2
3. 3
4. 4
5. 5

• 11
• 13
• 87
• 11
• 10
• Forum Statistics

• Total Topics
632973
• Total Posts
3009615
• Who's Online (See full list)

There are no registered users currently online

×