Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

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.

share|improve this question
add comment

1 Answer

up vote 1 down vote accepted

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)

----------

Thus, using your example again:

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.

share|improve this answer
    
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) –  The Trav 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. –  Valkea May 19 '11 at 2:03
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.