Object Models - Part II – Rotation © Copyright 2003-13, Howard J. Hamilton, University of Regina Rotation –exam Suppose that we know that we want to rotate a point (x, y) by an angle of b around the origin. We will call the new point (x’, y’). The problem is to find equations that tell us what x’ and y’ are in terms of x, y, and b. We know: cos(c) = x/(x2 + y2)½ sin(c) = y/(x2 + y2)½ and: sin(b + c) = y’/(x2 + y2)½ Thus: sin(b + c) = sin(b)cos(c) + cos(b)sin(c) 2 2 ½ y’/(x + y ) = sin(b)(x/(x2 + y2)½) + cos(b)(y/(x2 + y2)½ ) y’ = xsin(b) + ycos(b) where (x’, y’) is the new point and a = b + c is the new angle. Note: We can say that, because we are doing a rotation, (x2 + y2) ½ and (x’2 + y’2) ½ are of equal length. We can see that: cos(a) = cos(b + c) = x’/(x’2 + y’2)½ = x’/(x2 + y2)½ Thus: cos(b + c) = cos(b)cos(c) – sin(b)sin(c) 2 2 ½ x’/(x + y ) = cos(b)(x/(x2 + y2)½) – sin(b)(y/(x2 + y2)½ ) x’ = xcos(b) – ysin(b) Rotation Matrix – –exam We can see that: x’ = #1x + #2y y’ = #3x + #4y and we know that: x’ = xcos(b) – ysin(b) y’ = xsin(b) + ycos(b) If we rearrange the equations, we can see that: x’ = (cos(b) * x) + (–sin(b) * y) y’ = (sin(b) * x) + (cos(b) * y) Which correspond to: #1 #2 x’ = (cos(b) * x) + (–sin(b) * y) #3 #4 y’ = (sin(b) * x) + (cos(b) * y) And thus, we get our 2D rotation matrix: A question one might pose is: why is vector addition sufficient to solve the translation problem, while matrix multiplication is needed to solve the rotation problem? The simple answer is that rotation is harder to compute based on the (x, y) points than translation. A 2x2 matrix is required because we have two values in the input and we want two values in the output. Or we could say that both x and y contribute to the computation of x’ (two top elements in the array) and they also both contribute to the computation of y’ (two bottom elements). 3D Rotation – –exam, idea of three matrices for the three rotations In 3D, rotation matrices describing rotations about the Z, X, and Y axes look like this, as given in the course notes for CS 405. To understand why these matrices are 4-dimensional instead of 3, read about homogeneous coordinates in the course notes for CS 405. cos( a ) sin( a) sin( a ) cos( a ) R z (a) 0 0 0 0 0 1 0 cos( a ) R x (a) 0 sin( a ) 0 0 cos( a ) 0 0 1 R y (a) sin( a ) 0 0 0 0 0 0 0 1 0 0 1 0 0 sin( a ) 0 cos( a ) 0 0 1 sin( a ) 0 0 0 cos( a ) 0 0 1 In the Rz matrix, the cos and sin values are in the upper left two rows and columns. As you move to Rx and then Ry, you move the cos and sin values one position down and one position to the right. If you go outside the upper left 3x3 matrix, you wraparound. 3D Rotation Pictures – exam Notice that each of these rotations described by matrices in the previous section can be viewed as a 2D rotation in one of three planes: X-Y, Y-Z, or Z-X: A rotation that appears counterclockwise around the Z axis when viewed from the +Z side is a rotation in the X-Y plane. In OpenGL, such a counterclockwise rotation corresponds to a rotation by a positive angle. glRotate(positive_theta, 0, 0 , 1); A rotation that appears counterclockwise around the X axis when viewed from the +X side is a rotation in the Y-Z plane. In OpenGL, such a counterclockwise rotation corresponds to a rotation by a positive angle. glRotate(positive_theta, 1, 0 , 0); A rotation that appears counterclockwise around the Y axis when viewed from the +Y side is a rotation in the X-Z plane. In OpenGL, such a counterclockwise rotation corresponds to a rotation by a positive angle. glRotate(positive_theta, 0, 1 , 0); In the right-hand coordinate system, when you are staring down from the positive x, y, or z axis, the rotation around that axis is counterclockwise. By combining these rotations in sequence, an arbitrary 3D rotation can be achieved. This is called fixed angle representation. Fixed Angle Representation – exam, general idea of series of multiplications In fixed angle representation, successive rotations are applied around globally defined axes of rotation. The axes are fixed in global space and are not affected by the rotations that are applied to the object. Consider a rotation of a degrees around the X-axis followed by a rotation of b degrees about the Y-axis. - The combined rotation is represented in fixed-angle form by: Ry(b)Rx(a), where Rx and Ry are the 3D rotation matrices given above. - Don’t forget that all transformation matrices get applied in “reverse” order, since they are used to transform a point or vector via premultiplication, like so: P’ = [Ry(b)Rx(a)] P // transforms P to P’ by rotating first about the X-axis, then about the Y-axis. - Watch this example movie, showing the X and Y rotations applied in sequence. Example: Find the new position of point P = (0, 1, 0) after being rotated (in fixed angle form) about the X-axis by 45 degrees and the Yaxis by -60 degrees (assume an x-y-z rotation order). The rotation matrices that we need are Rx(45) and Ry(-60), where Rx and Ry are defined above. With an x-y-z rotation order, the rotations should be applied to point P like so: P' = [Ry(-60)Rx(45)] P First compute Ptemp = Rx(45) P 1 0 0 0 0 0 1 0 0 0 1 0 cos( 45) sin( 45) R x (45) 0 sin( 45) cos( 45) 0 0 0 Ptemp 1 0 R x (45) P 0 0 0 2 2 0 2 2 2 2 2 2 0 0 0 2 2 2 2 0 0 0 0 1 0 0 1 1 0 2 2 2 2 0 0 0 0 1 0 2 2 2 2 1 Now compute P' = [Ry(-60)Rx(45)] P = Ry(-60) Ptemp cos( 60) 0 R y (60) sin( 60) 0 P ' R y (60) Ptemp 0 sin( 60) 1 0 0 cos( 60) 0 0 1 2 0 0 1 0 0 1 3 3 2 0 0 0 1 0 0 0 1 2 0 3 2 0 0 1 0 0 3 2 0 1 2 0 6 0 4 2 2 2 2 2 0 0 0 1 Notice that the rotations in this example are very similar to those that appear in the example movie above. Once you become comfortable enough with 3D rotations to be able to visualize how they will turn out, you can use this skill to check your math. In the movie, it's clear that the tip of the arrow (point (0, 1, 0)) ultimately ends up in a position with a negative X-value and positive Y and Z-values. The P' that we found must satisfy these three conditions; fortunately, it does. Two problems with the fixed angle representation make it unsuitable for animation systems: if a rotation of 90 degrees is applied, two axes become aligned and it may be difficult to specify desired rotations it is not easy to interpolate between two orientations, each specified as a series of rotations. Example: Consider the effect of rotations Rx = -30, Ry = 90, and Rz = 0 Front of book Starting Position and Orientation First the rotation Rx = -30, would tilt the book backwards at the top (rotation around X axis). Front of Book After Rx Tilted back at top The rotation Ry = 90 spins the tilted book around the Y axis. The bottom left corner stays fixed to the origin. S p i n e Front of Book After Ry Aligned with Z axis on bottom, tilted into negative X at top The odd thing is that to reverse the rotation around the X axis applied in the previous step, we need to use a rotation around the Z axis, since the former X axis is now aligned with the Z axis. Why? Because the above rotation could be expressed more simply as Rx = 0, Ry = 90, and Rz = 30, as shown in Example 2 below. Example 2: Rx = 0, Ry = 90, and Rz = 30. Suppose the book is originally positioned as in Example 1. Rotating Rx = 0 has no effect. After rotating Ry = 90, the book is aligned with the Z axis. S pi ne Front of Book After Rx, Ry After rotating Rz = 30, the book is still aligned with the Z axis on the bottom, but it is tilted 30 degrees away from Z axis on top, just as in Example 1. S p i n e Front of Book (0, 90, 30) Euler Angle Representation –exam, general idea of series of multiplications As with the fixed angle representation, Euler angle representation involves combining rotations about a set of axes. The difference between the two is that the Euler angle representation uses the rotating object’s local axes, while fixed angle representation uses a global set of axes. Whenever an object is rotated, its local axes change. Given any rotation matrix and a vector representing one of the object’s current local axes, we can obtain the new local axis by applying the rotation matrix to the given axis. Example: For an object with local axes A1 = (1, 0, 0), A2 = (0, 1, 0), and A3 = (0, 0, 1), find the new set of local axes that will result from rotating the object by 30 degrees about A1. Review: to represent a 3D vector in 3D homogeneous coordinates, use a 1 as the 4th element: (0, 1, 0) becomes (0, 1, 0, 1). cos( a ) sin( a) 0 0 ) rotation cos( a ) 0matrix 0 A1 is parallel to the X-axis, sin( so athe needed to obtain the R z (a) 0 desired rotation is: 0 1 0 0 0 1 0 0 0 0 1 0 cos( a ) sin( a ) 0 R x (a) 0 sin( a ) cos( a ) 0 0 0 1 0 cos( a ) 0 sin( a ) 0 0 1 0 0 R y (a) With a = 30 degrees, cos(a) = asqrt(3)/2 = ½. sin( ) 0 cos( aand ) 0sin(a) 0 0 1 0 1 0 0 0 0 1 3 0 cos(30) sin( 30) 0 0 2 R x (30) 1 0 sin( 30) cos(30) 0 0 2 0 0 1 0 0 0 To find new axis for A2, we calculate as follows. 1 0 A2 ' Rx (30) A2 0 0 0 3 2 0 1 2 1 2 3 2 0 0 0 1 2 3 2 0 0 0 0 1 0 0 0 0 3 1 2 0 1 0 2 1 1 1 Dropping the 4th element to obtain a plain 3D vector, we get: 3 1 A2 ' 0, , 2 2 Similarly, A1 ' Rx (30) A1 1,0,0 1 3 A3 ' R x (30) A3 0, , 2 2 The local axis about which we were rotating (A1) remained unchanged, but the other two axes have been rotated about A1 by 30 degrees. Let’s reconsider the example used in the fixed angle representation section above (rotating by a degrees around the X-axis combined with a rotating of b degrees about the Y-axis): Using the formula given for fixed angle representation, P’ = [Ry(b)Rx(a)] P ANGLE REPRESENTATION WRONG FOR EULER this is the result: Euler angle movie. Why does the yellow arrow end up in a different orientation now? - Don’t forget: with Euler angle representation, all rotations are made about the object’s local axes. - In the movie, the yellow arrow represents the Y-axis of the local coordinate system of the point to be rotated and the light blue arrow represents its Z-axis. - These arrows are initially lined up with the global Y-axis and global Zaxis, respectively. - When the point on the yellow arrow is rotated by a degrees about its local X-axis (which is initially aligned with the global X-axis), its local Y and Z axes change. Thus, the yellow and light blue arrows move. - The object’s initial local X-axis is lined up with the global X-axis. The local X-axis is indicated with the red arrow. - Since the arrow was initially aligned with its local Y-axis, it remains aligned with its local Y-axis. - When the point on the yellow arrow is rotated by b degrees about its local Y-axis, it spins about its own Y-axis (yellow arrow) rather than about the global Y-axis (green arrow) as it did with fixed angle representation. As it turns out, we can obtain the same result as we had for the fixed angle representation by reversing the order in which we apply the rotations (Parent, Section 2.2.2): P’ = [Rx(a)Ry(b)] P See the result here: Euler angle movie 2. The Euler angle representation also suffers from the gimbal lock problem. Axis-Angle Representation – – not on exam While the fixed angle and Euler angle representations specify a given orientation using a combination of rotations about a standard set of axes (global X-Y-Z, or local axes), we can instead represent any orientation by a single rotation about an arbitrary axis. Suppose that we want to go from this orientation: to this orientation: in a single rotation about an arbitrary axis. Can we simply rotate 45 degrees about the X-axis? Pay close attention to the lights on the head of the yellow arrow - here's a close-up look: In the initial orientation, we can see the red and white lights, so if we rotate the arrow by 45 degrees about the X-axis, we should still be able to see the red and white lights. Looking at the final orientation, this is not the case - we can see the green and blue lights, but not the red and white lights. Here's why: In addition to being rotated by 45 degrees, the arrow has been spun about its axis by 180 degrees, like this: Euler angle movie 3. To achieve the desired orientation in a single rotation about an axis, we can define our axis of rotation to be a vertical line rotated by 22.5 degrees about the X-axis. By rotating the arrow about this axis by 180 degrees, we obtain the desired result: Axis angle movie. Rotating Points & Vectors using Axis-angle information – not on exam Given an axis (a, b, c) and angle T, we can apply the specified rotation to a point or vector P by constructing the following matrices, a a A b a c a a b bb c b a c b c c c 0 A* c b c 0 a b a 0 combining them in this formula, M A cos(T ) ( I A) sin( T ) A* and multiplying the result onto P: P' M P Derivation Suppose that we want to rotate a vector v about a unit-length axis n by T degrees. Given v and n in 3D Cartesian coordinates (with axes for the x, y, and z directions), we build a new coordinate system, C’, as follows: Begin with: n as the first axis, nxv as the second axis, and n x (n x v) as the third axis. We must now normalize the axes to obtain C’: Recall that the length of a cross product, u x w is: | u x w | = | u | | w | sin(Q) where Q is the angle between vectors u and w. The lengths of the 3 axes above are then: as unit-length) | n |= 1 (by definition of n | n x v | = | n | | v | sin(Q) the angle between n and v) = (1) | v | sin(Q) | n x v | = | v | sin(Q) (where Q is | n x (n x v) | = | n | | n x v | sin(90) between n and n x v is always 90) = (1) | n x v | (1) =|nxv| | n x (n x v) | = | v | sin(Q) (the angle Defining L = | v | sin(Q), the axes of C’ are now given by: axis n/|n| (n x v) / | n x v | = n = first axis = (n x v) / L = second [n x (n x v)] / | n x (n x v) | third axis = [n x (n x v)] / L = We can now express v as a sum of vectors along the first and third axes, since by the definition of the cross product, v lies in the plane defined by these axes. v = v// + v┴ where v// is the component of v that is parallel to n, and v┴ is the component of v that is perpendicular to n. The lengths of v// and v┴ are: | v// | = | v | cos(Q) | v┴ | = | v | sin(Q) = L Now, consider a rotation of v about n by T degrees, resulting in vector v’. We can obtain v’ by expressing it as a sum of two vectors, v’ = v//’ + v┴’ where v//’ and v┴’ are the result of rotating vectors v// and v┴ about n by T degrees, respectively. Under this rotation, will v// change? I.e., will its direction or length be different after the rotation? No, v// won’t change, since it is parallel to the axis of rotation, n. So, with v’ = v//’ + v┴’ we already have v//’ = v// How does v┴ change during the rotation? Since v┴ is perpendicular to the axis of rotation, it stays in the plane defined by the second and third axes of C’. This means that v┴ can be rotated in two dimensions: [n x (n x v)] / L (n x v) / L T | v┴’| cos(T) | v┴’| sin(T) v┴’ v┴ To see an illustration everything up to this point via 3D animation, watch this movie. (46 sec., 13.0 MB) By our construction of the axes of C’, v┴ is always parallel to the [n x (n x v)] / L axis, so the effect of this rotation is always easy to calculate. So, in C’, we have: v┴ = 0 * (n x v) / L + –| v┴ | * [n x (n x v)] / L = ( 0, –| v┴ | ) v┴ = ( 0, –L ) v┴’ = | v┴’| sin(T) * (n x v) / L + –| v┴’| cos(T) * [n x (n x v)] / L = ( | v┴’| sin(T), –| v┴’| cos(T) ) = ( | v┴ | sin(T), –| v┴ | cos(T) ) (the length of v┴ does not change) v┴’ = ( L sin(T), –L cos(T) ) Since v┴ has no component in the n direction, we can convert back to three dimensions by using 0 as the first term: v┴ = ( 0, 0, –L ) v┴’ = ( 0, L sin(T), –L cos(T) ) Written another way, v┴’ = v┴ + v┴’ – v┴ = v┴ + ( 0, L sin(T), –L cos(T) ) – ( 0, 0, –L ) = v┴ + ( 0, L sin(T), L – L cos(T) ) v┴’ = v┴ + L ( 0, sin(T), 1 – cos(T) ) We can now find v’, since v’ = v//’ + v┴’: Recall that v//’ = v// . v’ = v//’ + v┴’ = v// + v┴ + L ( 0, sin(T), 1 – cos(T) ) v’ = v + L ( 0, sin(T), 1 – cos(T) ) (since v = v// + v┴) Now, convert back to 3D Cartesian Coordinates by multiplying each term in ( 0, sin(T), 1 – cos(T) ) by the Cartesian form of its corresponding axis, like so: v’ = v + L ( 0, sin(T), 1 – cos(T) ) · ( n , (n x v) / L , [n x ( n x v )] / L ) = v + ( 0, sin(T), 1 – cos(T) ) · ( L * n , (n x v), [n x ( n x v )] ) = v + 0 * [ L * n ] + sin(T) * [n x v] + ( 1 – cos(T) ) * [n x ( n x v )] v’ = v + sin(T) * [n x v] + ( 1 – cos(T) ) * [n x ( n x v )] We can now find v’ in terms of v, n, and T, but it can be more convenient to write this equation in matrix form, as follows: At the beginning of this section, we defined two matrices. Here they are again, for reference: a a A b a c a a b bb c b a c b c c c 0 * c A b c 0 a b a 0 Let’s look more closely at A*. If we apply A* to an arbitrary vector, say v = ( x, y, z ), we obtain a vector like so: 0 ( A* )v c b c 0 a b x cy bz bz cy a y cx az cx az 0 z bx ay ay bx Does this look familiar? Consider the cross product ( a, b, c ) x ( x, y, z ). Using the matrixdeterminant form for evaluating cross products, we get: iˆ (a, b, c) ( x, y, z ) a x ˆj b y kˆ bz cy ˆ ˆ ˆ c (bz cy )i (cx az ) j (ay bx)k cx az ay bx z which is precisely what we had for the value of (A*)v above. So, (A*)v is really just a matrix formulation for (n x v), where n = ( a, b, c ) and v = ( x, y, z ). In general, 0 n v (a, b, c) ( x, y, z ) c b c 0 a b x a y 0 z This gives us a way to replace (n x v) in our formula, but what about [n x (n x v)]? To obtain a matrix form for [n x (n x v)], we apply the previous cross-product-to-matrix conversion using n and (n x v), i.e.: n (n v) (a, b, c) (n v) 0 c b c 0 a b a (n v) 0 0 c b c 0 a b 0 a c 0 b c 0 a b x a y 0 z b 0 a c 0 b c 0 a b x a y 0 z 0 c b c 0 a ( A* )( A* )v n ( n v ) ( A* ) 2 v We now have enough information to write our first matrix form for v’: v’ = v + sin(T) * [n x v] + ( 1 – cos(T) ) * [n x ( n x v )] v’ = v + sin(T) * (A*) v + ( 1 – cos(T) ) * (A*)2 v v’ = [ I + sin(T) * (A*) + ( 1 – cos(T) ) * (A*)2 ] v v’ = M v – cos(T) ) * (A*)2 where M = I + sin(T) * (A*) + ( 1 While this is an acceptable solution, (A*)2 isn’t a very nice matrix to construct directly: 0 ( A* ) 2 c b c 0 a c 2 b 2 ab ac b 0 a c 0 b c ba 2 c a2 bc ca cb 2 2 b a a 2 1 ba 2 * 2 ab b 1 (A ) ac bc 0 a b a 0 ca cb c 2 1 (since sqrt(a2 + b2 + c2) = 1) This representation can be improved by introducing Â, as defined above: a 2 1 ba 2 * 2 ab b 1 (A ) ac bc ca cb c 2 1 aa ab ac ( A* ) 2 ba bb bc ca 1 cb 0 cc 0 0 1 0 0 0 1 ˆ I A We can now update our first matrix form for v’: v’ = [ I + sin(T) * (A*) + ( 1 – cos(T) ) * (A*)2 ] v = [ I + sin(T) * (A*) + ( 1 – cos(T) ) * (Â – I) ] v = [ I + sin(T) * (A*) + (Â - I) – cos(T) * (Â – I) ] v = [Â + (I – I) + sin(T) * (A*) + cos(T) * (I – Â) ] v v’ = [Â + cos(T) * (I – Â) + sin(T) * (A*) ] v v’ = M v Where M is: M A cos(T ) ( I A) sin( T ) A* as given at the beginning of this section. QED. Example: Rotate the point P = (0, 2, 0) by 45 degrees about the axis (0, 0.7071, 0.7071). First, build the matrices: 00 A 0.7071 0 0.7071 0 0 0.7071 0 0.7071 0 0 0 0 1 0.7071 0.7071 0.7071 0.7071 0 1 / 2 1 / 2 0 2 0 0.7071 0.7071 0.7071 0.7071 0 1 / 2 1 / 2 0 1 1 0 1 1 0 A* 0.7071 0.7071 0.7071 0.7071 0 0 0 0.7071 0 0 0.7071 0.7071 0.7071 0 0 0 0 Now find M: M A cos(45)(I A) sin(45) A* 0 1 0 2 0 0 1 2 0 0 0 1 1 1 0 1 cos(45) 0 1 0 1 1 0 2 1 2 1 1 0 0 0 1 2 0 0 0 1 1 0 2 1 2 1 1 0 0 0 1 2 0 0 0 0 1 2 1 0.7071 2 0.7071 1 0 1 2 0 0 0 1 1 0 1 1 2 0 1 1 1 2 1 1 0 1/ 2 1/ 2 0 1/ 2 1/ 2 1 2 2 2 2 0 1 0 0 0 1 0 0 2 0 1 0 2 1 / 2 2 1 / 2 0 1 1 0 0.7071 - 0.7071 0 0 1 / 2 0.7071 1 / 2 - 0.7071 0.7071 0.7071 1/ 2 1 / 2 1/ 2 1 / 2 2 2 2 2 1 0 0 1 sin(45) 0.7071 - 0.7071 1 0.7071 0.7071 0 0 0 0 0.7071 0 0 0.7071 0 0 2 1 2 1 1 M 1 1 2 2 1 2 2 1 2 1 2 2 1 2 0.7071 0.5 0.5 0.8536 0.5 0.1465 0.5 0.1465 0.8536 Now apply M to P to obtain P': 0.7071 0.5 P' M P 0.5 0.8536 0.5 0.1465 0.5 0 1 0.1465 2 1.7071 0.8536 0 0.2929 Therefore the rotated point is P' = (-1, 1.7071, 0.2929).