Jump to content
  • Advertisement
Sign in to follow this  
Zaxx

Finding normal of arbitrary line.

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

If you intended to correct an error in the post then please contact us.

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 this post


Link to post
Share on other sites
Advertisement
Guest Anonymous Poster
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 this post


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

:D

Share this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!