# How do I rotate a segment + normal so that the normal is (0,-1) and the segment is now axis aligned

I have an arbitrary line segment, which may or may not be axis aligned along with its normal eg: Segment(Coord(-1,-1), Coord(1,1), Coord(-1, 1).normalize) which represents a line segment with a 45 degree angle.

My desire is to transform that line to Segment(a:Coord, b:Coord, Coord(0,1))

I have a beginners understanding of how transformation matrixes work, in that I know I can get a rotation matrix and apply it to each of the Coords and I'll be left with my segment in the coordinate space I want.

I do not however, know how to calculate that rotation matrix given I know the start normal and the desired end normal.

The classical 2D (row) matrix is:

R(θ) = [ cosθ, sinθ ]
[-sinθ, cosθ ]

## ----------

Thus, using your example (45°) the (row) matrix would be:

R(-45°) = [ 0,7071, -0,7071 ]
[ 0,7071,  0,7071 ]


And if we consider your points [-1,-1] and [1,1] the result would be:

P([-1,-1])R(-45°) = [ -1, -1 ][ 0,7071, -0,7071 ]
[ 0,7071,  0,7071 ]

= [(-1*0.7071)+(-1*0.7071), (-1*-0.7071)+(-1*0.7071)]
= [ -1.41, 0 ]

P([1,1])R(-45°) = [ 1, 1 ][ 0,7071, -0,7071 ]
[ 0,7071,  0,7071 ]

= [(1*0.7071)+(1*0.7071), (1*-0.7071)+(1*0.7071)]
= [ 1.41, 0 ]


But I guess you need to calculate the angle too.

You can do it using the dot product of the vector representing the line and an axis (say [1,0]).

Let:

• A the ray vector obtained from [Point2 - Point1] (take care to avoid zero vector)
• B the base axis used as reference [1, 0] or [0, 1]

A·B = ||A|| ||B|| cosθ     <===>     θ = acos( A·B / (||A|| ||B||) )

• ||A|| = square_root( Ax² + Ay² )
• ||B|| = square_root( Bx² + By² )
• A·B = (Ax*Bx)+(Ay*By)

## ----------

A = Point2 - Point1 = [1-(-1), 1-(-1)] = [2, 2]
B = the x axis = [1, 0]

||A|| = square_root( 2² + 2² ) = 2,8284...
||B|| = square_root( 1² + 0² ) = 1
A·B = (2*1)+(2*0) = 2

θ = acos( 2 / (2,8284 * 1) ) = acos( 0.7071 ) = 45°


The line was rotated by 45°, so you need to rotate -45° to realign with axis.

Edit: hum I used [0,1] as normal target, because this is what we can read in your text, but now I see that you specified [0,-1] in your title. Anyway the technique should remain OK.

• It's the right answer, but I seem to be getting lost in the concepts... at some point you seem to have stopped looking at the normal [0,1] and started using the perpendicular to the normal? oh I see, you're taking the line, and aligning it to the x axis, which is what I want to do, it's just that you don't really need the normal to do it (although doesn't using the normal make sure the rotation happens in the expected direction? or is that just ordering of A and B) May 19 '11 at 1:54
• Well I did not used the normal because it was not needed. But you can dot-product the normal with the axis that must be aligned with the normal to compute the required angle (-angle) instead of using the dot-product of segment and the axis that must be aligned with this segment. May 19 '11 at 2:03