270 likes | 295 Views
2D GEOMETRICAL TRANSFORMATIONS. Plane. Example: J2_0_2DTransform. We have:. y. P. d. x. y. d. P’. x. 2D TRANSFORMATIONS. Translate. or. Scale. or. P’ = RP. Rotate. x’ = rcos( a+q ); y’ = rsin( a+q ); x’ = r(cos a cos q – sin a sin q );
E N D
2D GEOMETRICAL TRANSFORMATIONS Plane Example: J2_0_2DTransform @2017 by Jim X. Chen George Mason University
We have: y P d x y d P’ x 2D TRANSFORMATIONS • Translate @2017 by Jim X. Chen George Mason University
or • Scale @2017 by Jim X. Chen George Mason University
or P’ = RP • Rotate x’ = rcos(a+q); y’ = rsin(a+q); x’ = r(cosa cosq – sina sinq); y’ = r(sina cosq + cosa sinq); r a @2017 by Jim X. Chen George Mason University
That is, P’ = T(dx,dy) P That is, P’ = S (Sx,Sy) P That is, P’ = R(q) P 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. @2017 by Jim X. Chen George Mason University
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(q); // M<= MR(q); my2dScalef(float sx, float sy); // M<=MS(sx, sy); Example: J2_0_2DTransform @2017 by Jim X. Chen George Mason University
Combination of translations and transformation matrix p’ ( ) ( ) = = ' ' ' ' p T d , d P , P T d , d P 1 1 2 2 x y x y p p’’ ( ) ( ) = ' ' p T d , d T d , d P 2 2 1 1 x y x y 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); } Note that transformation matrix is uniform for all vertices, so it is in general generated and sent to vertex shaders as uniform. @2017 by Jim X. Chen George Mason University
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]); } @2017 by Jim X. Chen George Mason University
Transformation and Viewing To rotate about a point P1 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(-q)T(-x1, -y1) COMPOSITION OF 2D TRANSFORMATION Plane Lab 2D Examples g C f y B f b A f a o x Example J2_1_Clock2d @2017 by Jim X. Chen George Mason University
h Initial position: Step 1. translate: Step 2. rotate: Step 3. translate: h' Destination: h = T(-x ,-y )h h R(- q )h h' = T(x ,y )h = 1 0 0 0 0 2 2 1 h h(x ,y ) 1 1 q h' ( x' , y' ) h (x ,y ) h' 1 1 1 11 11 c(x ,y ) c(x ,y ) 0 0 h (x ,y ) 0 0 2 12 12 x x x x Example 1: draw a current time clock in 2D space y y y y h’=T(c)R(-q)T(-c)h drawHand(c, h’); x' 1 0 x 1 0 x – x q q cos sin 0 1 0 0 1 = q q y' 0 1 y – sin cos 0 0 1 y – y 1 0 0 1 0 0 1 1 0 0 1 0 0 1 1 @2017 by Jim X. Chen George Mason University
h’=T(c)R(-q)T(-c)h drawHand(c, h’); Float matrix[3][3]; my2dLoadIdentity(); my2dTranslatef(x0, y0); my2dRotatef(-q); my2dTranslatef(-x0, -y0); transDraw(c, h); //transVertex(V, V1); @2017 by Jim X. Chen George Mason University
J2_1_Clock2d public void display(GLAutoDrawable glDrawable) { my2dLoadIdentity(); my2dTranslatef(c[0], c[1]); my2dRotatef(-hAngle); my2dTranslatef(-c[0], -c[1]); transDrawClock(c, h); } @2017 by Jim X. Chen George Mason University
Example 2: Reshape a rectangular area: Example: J2_2_Reshape 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 @2017 by Jim X. Chen George Mason University
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; …… y e.getX(), e.getY() Mouse (0,0) v1 x v0 P1 @2017 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 P1 in (x, y) coordinates 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; } y e.getX(), e.getY() Mouse (0,0) v1 x v0 @2017 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]); … } @2017 by Jim X. Chen George Mason University
g C a a a A’ = R( ) A; B’ = R( ) B; C’ = R( ) C; b B’’ = T(A’) R( ) T(-A’) B’; y b C’’ = T(A’) R( ) T(-A’) C’; B g y C = T(B’’) R( ) T(-B’’) C’’; f b A a B A C o x x o The initial A, B, and C are at arbitrary positions. Robot Arm Example 3: draw an arbitrary 2D robot arm: Example: J2_3_Robot2d @2017 by Jim X. Chen George Mason University
@2017 by Jim X. Chen George Mason University
Initial position: (A, B, C) Final position g C ’ f ’ C y y y y B C’ B f f Step 2 Step 3 Step 1 b b B’ A A A f f f B A C a a a x o x o x o o x 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); @2017 by Jim X. Chen George Mason University
y y C’’ g Step 2 C’ B’ B g b A A x o o x Method II: g C f y y B Step 1 f b A f B A C a x o o 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); @2017 by Jim X. Chen George Mason University
y a+b+g y a+b+g B f ’ ’ ’ Step 2 B C C a+b a+b A A f f a a o o x 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 g C f y y B Step 1 f Step 3 b A f B A C a x o o x Af = R(a)A; Bf = T(Af)T(-A)B’ =T(Af)R(a+b)T(-A)B; Cf = T(Bf)T(-B)C’ =T(Bf)R(a+b+g)T(-B)C. @2017 by Jim X. Chen George Mason University
TRANSFORMATION MATRIX STACK • Need multiple matrices to save different states • Matrix stack Float matrix[POINTER][3][3]; • myPushMatrix(); • pointer++; • copy the matrix from (pointer – 1); • myPopMatrix(); • pointer--; multiply @2017 by Jim X. Chen George Mason University
Matrix Stack J2_2_Reshape J2_2_ReshapePushPop 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(); my2dLoadIdentity(); my2dTranslatef(P1[0], P1[1]); my2dScalef(sx, sy); my2dTranslatef(-v0[0], -v0[1]); my2dTranslatef(c[0], c[1]); my2dRotatef(-hAngle); my2dTranslatef(-c[0], -c[1]); transDrawClock(c, h); At this point of program running, the two current matrices on the matrix stacks are different: so the future transformations are different @2017 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 sync with display refresh // to avoid rendering too fast gl.setSwapInterval(1); } @2017 by Jim X. Chen George Mason University
OpenGL Transformation Implementation Example: J2_3_Robot2d Example: J2_4_Robot gl.glLoadIdentity(); drawArm(O, A); 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); 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); my2dLoadIdentity(); transDrawArm(O, A); my2dTranslatef(A[0], A[1]); my2dRotatef(b); my2dTranslatef(-A[0], -A[1]); transDrawArm(A, B); my2dTranslatef(B[0], B[1]); my2dRotatef(g); my2dTranslatef(-B[0], -B[1]); transDrawArm(B, C); @2017 by Jim X. Chen George Mason University
OpenGL 4.x • Current matrix is uniform for all vertices of an object • mat4 is used to define a 4x4 matrix, which can be defined as a uniform for the vertex shader. • Matrix multiplications are available in both JOGL and GLSL. @2017 by Jim X. Chen George Mason University