Transformation and Viewing Plane Example: J2_0_2DTransform Copyright @ 2002 by Jim X. Chen George Mason University .1. Transformation and Viewing 2D TRANSFORMATIONS • Translate y' y d y x x dx ' x P y x' P ' y We have: P P T ' d x T d y ' y dy dx P P’ x Copyright @ 2002 by Jim X. Chen George Mason University .2. Transformation and Viewing Before scaling After scaling by (2, 2) y y P P x x • Scale x x sx ' x ' sx ' 0 y y' y sy 0 x s y y or Copyright @ 2002 by Jim X. Chen George Mason University P' S P .3. Transformation and Viewing • Rotate x' x cos y sin sin x cos y or P’ = RP y P’ x ' cos ' y sin y ' x sin y cos x’ = rcos(a); y’ = rsin(a); x’ = r(cosa cos – sina sin); y’ = r(sina cos + cosa sin); Copyright @ 2002 by Jim X. Chen George Mason University r a P x .4. Transformation and Viewing Homogeneous coordinates P’ = T+P; P’ = S*P; P’ = R*P; • If points are expressed in homogeneous coordinates, all three transformations can be treated as multiplications. x ' 1 0 d x x ' y y 0 1 d y 1 0 0 1 1 That is, P’ = T(dx,dy) P x ' sx ' y 0 1 0 That is, P’ = S (Sx,Sy) P 0 sy x ' cos ' y sin 1 0 0 0 x 0 y 1 1 sin cos 0 0 x 0 y 1 1 That is, P’ = R() P Copyright @ 2002 by Jim X. Chen George Mason University .5. Transformation and Viewing Implementation (my2dGL) Float M[3][3]; // Current Matrix multiply // Let’s say the current matrix on matrix[3][3] is M my2dLoadIdentity();// M<=I; my2dTranslatef(float dx, float dy); // M<=MT(dx, dy); my2dRotatef(); // M<= MR(); my2dScalef(float sx, float sy); // M<=MS(sx, sy); Example: J2_0_2DTransform Copyright @ 2002 by Jim X. Chen George Mason University .6. Transformation and Viewing • Combination of translations and transformation matrix p’ p' T (d , d )P, P '' T (d , d )P ' x1 y1 x2 y2 p '' T (d x 2 , d y 2 ) T (d x1 , d y1 )P p’’ p Float matrix[3][3]; my2dLoadIdentity(); my2dTranslatef(dx2,dy2); my2dTranslatef(dx1,dy1); transDraw(p); // what is transDraw? transDraw(object); // vertices are transformed first // before rendering transDraw(float x, y) { mult(&x, &y, matrix); // (x, y) is transformed by the matrix Draw(x, y); } Copyright @ 2002 by Jim X. Chen George Mason University .7. Example: J2_0_2DTransform public void display(GLAutoDrawable drawable) { if (cnt<1||cnt>200) { flip = -flip; } cnt = cnt+flip; gl.glClear(GL.GL_COLOR_BUFFER_BIT); // white triangle is scaled gl.glColor3f(1, 1, 1); my2dLoadIdentity(); my2dScalef(cnt, cnt); transDrawTriangle(vdata[0], vdata[1], vdata[2]); // red triangle is rotated and scaled gl.glColor3f(1, 0, 0); my2dRotatef((float)cnt/15); transDrawTriangle(vdata[0], vdata[1], vdata[2]); // green triangle is translated, rotated, and scaled gl.glColor3f(0, 1, 0); my2dTranslatef((float)cnt/100, 0.0f); transDrawTriangle(vdata[0], vdata[1], vdata[2]); } Copyright @ 2002 by Jim X. Chen George Mason University Transformation and Viewing COMPOSITION OF 2D TRANSFORMATION To rotate about a point P1 Plane Lab 1. Translate so that P1 is at the origin 2. Rotate 3. Translate so that the point returns to P1(x1, y1) T(x1, y1)R()T(-x1, -y1) 2D Examples y h(x1 ,y1) c(x 0,y0 ) y h' Af x a o x Example J2_1_Clock2d Copyright @ 2002 by Jim X. Chen George Mason University .9. Transformation and Viewing Example 1: draw a current time clock in 2D space Initial position:h Destination:h' y Step 1. translate: Step 2. rotate: Step 3. translate: h1 = T(-x0,-y0 )h h2 = R(-)h1 h' = T(x0 ,y0)h2 y h(x1 ,y1) c(x0,y0 ) h h1 (x11,y11) h' y y x h2 (x12,y12) c(x0,y0 ) h'(x'1,y'1 ) x x h’=T(c)R(-)T(-c)h drawHand(c, h’); x 1 0 x0 cos sin 0 1 0 – x0 x 1 y' 1 = 0 1 y0 – sin cos 0 0 1 – y0 y 1 0 0 1 0 0 1 1 1 0 0 1 x' 1 Copyright @ 2002 by Jim X. Chen George Mason University .10. Transformation and Viewing Initial position: h Destination: h' y Step 1. translate: Step 2. rotate: Step 3. translate: h1 = T(-x0,-y0 )h h2 = R(-)h1 h' = T(x0 ,y 0)h2 y h(x1 ,y1) c(x 0,y0 ) h1 (x11 ,y11 ) h' y y x h2 (x 12,y12) c(x 0,y0 ) x x h’=T(c)R(-)T(-c)h h h'(x' 1,y'1 ) x Float matrix[3][3]; drawHand(c, h’); my2dLoadIdentity(); my2dTranslatef(x0, y0); my2dRotatef(-); my2dTranslatef(-x0, -y0); transDraw(c, h); //transVertex(V, V1); Copyright @ 2002 by Jim X. Chen George Mason University .11. J2_1_Clock2d public void display(GLAutoDrawable glDrawable) { my2dLoadIdentity(); my2dTranslatef(c[0], c[1]); my2dRotatef(-hAngle); my2dTranslatef(-c[0], -c[1]); transDrawClock(c, h); } Copyright @ 2002 by Jim X. Chen George Mason University Transformation and Viewing Example 2: Reshape a rectangular area: Example: J2_2_Reshape Before reshaping Translate p1 After reshaping sx = d/c sy = b/a Scale a p2 b c Translate d After reshaping, the area and all the vertices (or models) in the area go through the same transformation T(P2)S(sx,sy)T(-P1)P Copyright @ 2002 by Jim X. Chen George Mason University .13. J2_2_Reshape: Mouse public class J2_2_ReshapePushPop extends J2_1_Clock2d implements MouseMotionListener { // the point to be dragged as the lowerleft corner private static float P1[] = {-WIDTH/4, -HEIGHT/4}; // the lowerleft and upperright corners of the rectangle private static float v0[] = {-WIDTH/4, -HEIGHT/4}; private static float v1[] = {WIDTH/4, HEIGHT/4}; // reshape scale value private float sx = 1, sy = 1; …… Copyright @ 2002 by Jim X. Chen George Mason University J2_2_Reshape: Mouse public class J2_2_ReshapePushPop extends J2_1_Clock2d implements MouseMotionListener { …… // when mouse is dragged, a new lowerleft point and scale value for the rectangular area public void mouseDragged(MouseEvent e) { float wd1 = v1[0]-v0[0]; float ht1 = v1[1]-v0[1]; // The mouse location, new lowerleft corner P1[0] = e.getX()-WIDTH/2; P1[1] = HEIGHT/2-e.getY(); float wd2 = v1[0]-P1[0]; float ht2 = v1[1]-P1[1]; // scale value of the current rectangular area sx = wd2/wd1; sy = ht2/ht1; } Copyright @ 2002 by Jim X. Chen George Mason University J2_2_Reshape: display public void display(GLAutoDrawable glDrawable) { // reshape according to the current scale my2dLoadIdentity(); my2dTranslatef(P1[0], P1[1]); my2dScalef(sx, sy); my2dTranslatef(-v0[0], -v0[1]); … } Copyright @ 2002 by Jim X. Chen George Mason University Transformation and Viewing Robot Arm Example 3: draw an arbitrary 2D robot arm: Example: J2_3_Robot2d y A’ = R(a) A; B’ = R(a) B; C’ = R(a) C; B’’ = T(A’) R(b) T(-A’) B’; y C’’ = T(A’) R(b) T(-A’) C’; Cf = T(B’’) R(g) T(-B’’) C’’; A o B C a o x x The initial A, B, and C are at arbitrary positions. Copyright @ 2002 by Jim X. Chen George Mason University .17. Initial position: (A, B, C) C’ ’ C f Final position y y C’ Step 1 B’ Af A B o C y y Bf Step 2 Bf Step 3 b Af a x Af a x o o y o C’ Step 1 x o x Method II: abg Af Method III: o ab Af a x abg Bf ’ B’ y Step 2 C y C’ Step 1 Step 3 b A x o g B’ g B A C’’ Step 2 o Copyright @ 2002 by Jim X. Chen George Mason University b a x Method I: y g ab Step 3 a x Initial position: (A, B, C) y Final position y C’ Step 1 Af A B o C x B’ y Step 3 Af a o y Step 2 Af a x o a x o Method I: Float matrix[3][3]; my2dLoadIdentity(); // Af=R(a)A; B1=R(a)B; C1=R(a)C; my2dRotatef(a); transVertex(A, Af); transVertex(B, B1); transVertex(C, C1); Draw (O, Af); my2dLoadIdentity(); // M=T(Af)R(b)T(-Af); my2dTranslatev(Af); my2dRotatef(b); my2dTranslatev(-Af); //Bf=MB1; C2=MC1 transVertex(B1, Bf); transVertex(C1, C2); Draw(Af, Bf); my2dLoadIdentity(); // M = T(Bf)R(g)T(-Bf); my2dTranslatev(Bf); my2dRotatef(g); my2dTranslatev(-Bf); transVertex(C2, Cf); Draw(Bf, Cf); Copyright @ 2002 by Jim X. Chen George Mason University x y y y Step 1 Step 2 C’ A B C o x A o B’ g B x y C’’ A o Method II: x Af = R(a)A; Bf = R(a)B’ = R(a)T(A)R(b)T(-A)B; Cf= R(a)C’’ = R(a)T(A)R(b)T(-A)T(B)R(g)T(-B)C. OpenGL doesn’t return the transformed positions Float matrix[3][3]; my2dLoadIdentity(); my2dRotatef(a); transDraw(O, A); // I*R(a) // we may consider local coordinates: origin at A my2dTranslatev(A); my2dRotatef(b); my2dTranslatev(-A); transDraw(A, B); // I*R(a)T(A)R(b)T(-A) // we may consider local coordinates: origin at B my2dTranslatev(B); my2dRotatef(g); my2dTranslatev(-B); transDraw(B, C); Copyright @ 2002 by Jim X. Chen George Mason University Af b a o x Float matrix[3][3]; my2dLoadIdentity(); my2dRotatef(a); transVertex(A, Af); Draw (O, Af); my2dLoadIdentity(); my2dTranslatev(Af); my2dRotatef(a + b); my2dTranslatev(-A); transVertex(B, Bf); Draw (Af, Bf); my2dLoadIdentity(); my2dTranslatev(Bf); my2dRotatef(a + b g); my2dTranslatev(-B); transVertex(C2, Cf); Draw(Bf, Cf); Final position y abg y Step 1 A o B C Af x o ab y Step 2 Af a x o ab abg Step 3 Af a a x Af = R(a)A; Bf = T(Af)T(-A)B’ =T(Af)R(ab)T(-A)B; Cf = T(Bf)T(-B)C’ =T(Bf)R(abg)T(-B)C. Copyright @ 2002 by Jim X. Chen George Mason University y o x Transformation and Viewing TRANSFORMATION MATRIX STACK •Simulate a real clock? •Animate robot arm? •Need multiple matrices to save different states? •Matrix stack Float matrix[POINTER][3][3]; • myPushMatrix(); multiply • pointer++; • copy the matrix from (pointer – 1); • myPopMatrix(); • pointer--; Copyright @ 2002 by Jim X. Chen George Mason University .22. Matrix Stack J2_2_Reshape J2_2_ReshapePushPop my2dLoadIdentity(); my2dTranslatef(P1[0], P1[1]); my2dScalef(sx, sy); my2dTranslatef(-v0[0], -v0[1]); my2dTranslatef(c[0], c[1]); my2dScalef(1.2f, 1.2f); my2dRotatef(-hAngle); my2dTranslatef(-c[0], -c[1]); transDrawClock(c, h); my2dLoadIdentity(); my2dTranslatef(P1[0], P1[1]); my2dScalef(sx, sy); my2dTranslatef(-v0[0], -v0[1]); my2dPushMatrix(); my2dTranslatef(c[0], c[1]); my2dRotatef(-hAngle); my2dTranslatef(-c[0], -c[1]); transDrawClock(c, h); my2dPopMatrix(); At this point of program running, the current matrix on the matrix stack is different Copyright @ 2002 by Jim X. Chen George Mason University OpenGL Matrix Stacks & Transformation public void reshape(GLAutoDrawable drawable, int x, int y, int w, int h) { super.reshape(drawable, x, y, w, h); //1. specify drawing into only the back_buffer gl.glDrawBuffer(GL.GL_BACK); //2. origin at the center of the drawing area gl.glMatrixMode(GL.GL_PROJECTION); gl.glLoadIdentity(); gl.glOrtho(-w / 2, w / 2, -h / 2, h / 2, -1, 1); // matrix operations on MODELVIEW matrix stack gl.glMatrixMode(GL.GL_MODELVIEW); gl.glLoadIdentity(); //3. interval to swap buffers to avoid rendering too fast gl.setSwapInterval(1); } Copyright @ 2002 by Jim X. Chen George Mason University OpenGL Transformation Implementation Example: J2_3_Robot2d Example: J2_4_Robot my2dLoadIdentity(); transDrawArm(O, A); gl.glLoadIdentity(); drawArm(O, A); my2dTranslatef(A[0], A[1]); my2dRotatef(b); my2dTranslatef(-A[0], -A[1]); transDrawArm(A, B); gl.glTranslatef(A[0], A[1], 0.0f); gl.glRotatef(beta, 0.0f, 0.0f, 1.0f); gl.glTranslatef(-A[0], -A[1], 0.0f); drawArm(A, B); my2dTranslatef(B[0], B[1]); my2dRotatef(g); my2dTranslatef(-B[0], -B[1]); transDrawArm(B, C); gl.glTranslatef(B[0], B[1], 0.0f); gl.glRotatef(gama, 0.0f, 0.0f, 1.0f); gl.glTranslatef(-B[0], -B[1], 0.0f); drawArm(B, C); Copyright @ 2002 by Jim X. Chen George Mason University Transformation and Viewing Homework 1. Build up your own matrix system that includes - Double matrix[POINTER][3][3]; - void my2dLoadIdentity(); - void my2dTranslated(double x, double y); - void my2dRotated(double a); - void my2dScaled(double x, double y); - void myTransVertex(double x, double y, double x1, double y1); - void my2dPushMatrix(); - void my2dPopMatrix(); 2. Use your system to achieve the rotation of your pentagon or other objects in your circle. Then, you add a clock hand at each vertex of your pentagon or objects. Copyright @ 2002 by Jim X. Chen George Mason University .26. HW5: 2012 Fall Class 1. 2. 3. 4. Continue from previous homework; Modify your code: draw a unit-size sphere at the origin; Using OpenGL transformation on MODELVIEW Matrix Stack, rotate, scale, and translate the spheres to the locations in animation; (40%) Use PushMatrix and PopMatrix on the Matrix Stack (40%) Copyright @ 2006 by Jim X. Chen: jchen@cs.gmu.edu 27