Finding the normal to a 2d line

Started by
7 comments, last by xytor 12 years, 2 months ago
Basically I've got two points: (x1, y1), (x2, y2) that form a line(duh) and I want to find a vector perpendicular to that line so i can turn it into a unit normal. I'm frightened because this seems like it should be real easy to figure out ,but I've searched up and down Gamedev and Google and can't find what I want. The closest I've gotten was something another thread suggested: finding the perp-dot product of the two vectors. But I don't know what to do with it once I've found it :(. Any suggestions?
Advertisement
There are two normals (if you stay in 2D), one into each half-space defined by the original line.

If the lines are ordered, and you want the counter-clockwise normal, then it's simple to see what to do.

First, generate the rotation matrix that will rotate a point by 90 degrees counterclockwise in 2D. I'm assuming row vertices on the left:
          0   1 [x y] *          = [Xn Yn]         -1   0


Then, generate the tangent for the line:

[Xt Yt] = [x2 y2]-[x1 y1] = [x2-x1 y2-y1]


Last, rotate through the matrix and simplify:

                             0   1  [Xn Yn] = [x2-x1 y2-y1] *         =  [x1-x2 y2-y1]                            -1   0


(Watch the order!)

Normalize and you have the actual normal. The clockwise normal would be the 90 degree rotation the other way.
enum Bool { True, False, FileNotFound };
I should have been able to figure that out :P. Isn't what you showed above the clockwise rotation though? I mean if we have points (4, 0) and (0, 4) putting it into that equation gives

[x1-x2, y2-y1]
[4 - 0, 4 - 0]

[4, 4]

which is clockwise.
Quote:Original post by hplus0603
                             0   1  [Xn Yn] = [x2-x1 y2-y1] *         =  [x1-x2 y2-y1]                            -1   0

                             0   1  [Xn Yn] = [x2-x1 y2-y1] *         =  [y1-y2 x2-x1]                            -1   0
Clockwise would be
                             0  -1  [Xn Yn] = [x2-x1 y2-y1] *         =  [y2-y1 x1-x2]                             1   0
John BoltonLocomotive Games (THQ)Current Project: Destroy All Humans (Wii). IN STORES NOW!
If the line formula is defined as: y = m * x
where m = dy/dx = (y2-y1)/(x2-x1)

Then the perpendicular line is defined as:
y = m'*x
where m' = -1/m = -(dx/dy) = -dx/dy = dx/-dy

So you have two solutiond for m'
m' = -dx/dy
so m' = x1-x2/y2-y1 (1)

or m' = dx/-dy
so m' = x2-x1/y1-y2 (2)

Which are the solutions HPPlus presented

Luck!
Guimo
i belive you could just:

v is the direction of the line

n1 is the first "normal"
n2 is the second

n1<-v.y, v.x>
n2<v.y, -v.x>

normalize them if necessary.

of course i'm assuming you're defineing the line as a segment with two endpoints or in terms of a vector and a point.
Much easier way:

1) Find the direction of the line by subtracting one point from the other
2) Convert the direction into a 3D vector, leave z as 0.
3) do a cross product with (0,0,1)
4) normalize the result

Voila, you have the normal to the line!

So you have two solutiond for m'
m' = -dx/dy
so m' = x1-x2/y2-y1 (1)

or m' = dx/-dy
so m' = x2-x1/y1-y2 (2)

Which are the solutions HPPlus presented

Careful with this approach, as you need to handle the case when y1-y2 is zero.


Much easier way:

1) Find the direction of the line by subtracting one point from the other
2) Convert the direction into a 3D vector, leave z as 0.
3) do a cross product with (0,0,1)
4) normalize the result

Voila, you have the normal to the line!

Not everyone working with 2D space has a 3D math library readily available. Hplus' approach makes the most sense (with an thorough explanation even!) and avoids 6 multiplications, 3 subtractions, and storage overhead for z component and the extra vector.

Not everyone working with 2D space has a 3D math library readily available. Hplus' approach makes the most sense (with an thorough explanation even!) and avoids 6 multiplications, 3 subtractions, and storage overhead for z component and the extra vector.


It's super cheap and easy to make your own cross product function that takes one 2d vector, assumes the z is 0 and crosses it with (0,0,1).

Here, let me give you the exact formula:
Given a 2d vector (a,b), the normal is (x,y):
x = b
y = -a

So basically, flip a and b, and negate the y. Two assignments and one negation. Can't be cheaper!

This topic is closed to new replies.

Advertisement