Self study objectives:
1. Master the mathematical principle of two-dimensional transformation
2. Learn to apply two-dimensional transformation
#define GLUT_DISABLE_ATEXIT_HACK #include "GLUT.H" #include<math.h> #include <string.h> #define ZVALUE 20.0f int w_width = 600; int w_height = 600; int lineWidth; //Nonhomogeneous two-dimensional geometric transformation struct my_v_inhomogenous { int x; int y; }; struct my_v_inhomogeneous rectangle[4]; /// /// /// // //A little brother forgot / void init(void) { rectangle[0].x = 0; rectangle[0].y = 0; rectangle[1].x = 80; rectangle[1].y = 0; rectangle[2].x = 80; rectangle[2].y = 40; rectangle[3].x = 0; rectangle[3].y = 40; } //DDA draw line void DDA(int x0, int y0, int x1, int y1) { float dx = x1 - x0; float dy = y1 - y0; float k = dy / dx; float x = x0; float y = y0; //y(i+1)=yi+k; The formula y=kx+b is used //xi,yi,int(y(i+1)+0.5). //The slope is too large to be discrete //Generally speaking, k and y are integers, and y must be rounded in each operation, so the operation efficiency is relatively low while (x <= x1) { glVertex2d(x, y); x++; y = floor(y + k + 0.5); } } void Bresenham(int x0, int y0, int x1, int y1) //Only int type addition, subtraction and comparison //Draw the horizontal and vertical lines separately, and divide the others into eight parts //Only the first quadrant is written here //Traverse each abscissa and find the ordinate corresponding to the abscissa { int dy = y1 - y0; int dx = x1 - x0; int xf = x0; int yf = y0; int e = -dx; while (xf < x1) { glColor3f(1.0, 0.0, 0.0); glVertex2d(xf, yf); e = e + 2 * dy; if (e > 0) { yf++; xf++; e = e - 2 * dx; } else { xf++; } } } //Draw a circle void draw_circle(int r) { int x, y; x = 0, y = r; int d = 3 - 2 * r; while (x <= y) { glColor3f(0.0, 1.0, 0.0); glVertex2d(x, y); glVertex2d(-x, y); glVertex2d(x, -y); glVertex2d(y, x); glVertex2d(-x, -y); glVertex2d(-y, -x); glVertex2d(y, -x); glVertex2d(-y, x); if (d > 0) { d += 4 * (x - y) + 10; y--; } else { d += 4 * x + 6; } x++; } } //Draw content void display(void) { glClearColor(1.f, 1.f, 1.f, 0.f); glClear(GL_COLOR_BUFFER_BIT); glPushMatrix(); glColor3b(0, 0, 1); glBegin(GL_POINTS); //GL_POINTS DDA(0, 0, 300, 1200); Bresenham(-100, -100, +200, 12200); draw_circle(100); glEnd(); glBegin(GL_POLYGON); //GL_LINE_LOOP for (int vIndex = 0; vIndex < 3; vIndex++) { glVertex2i(rectangle[vIndex].x, rectangle[vIndex].y); glVertex2i(rectangle[vIndex + 1].x, rectangle[vIndex + 1].y); } glEnd(); glutSwapBuffers(); glPopMatrix(); glFlush(); } void my_traslate_inhomogeneous(struct my_v_inhomogeneous* polygon, int polygon_vertex_count, int tx, int ty) { for (int vIndex = 0; vIndex < polygon_vertex_count; vIndex++) { polygon[vIndex].x += tx; polygon[vIndex].y += ty; } } //Projection mode, modelview mode, etc void reshape(int w, int h) { glViewport(0, 0, (GLsizei)w_width, (GLsizei)w_height);//Viewport size glMatrixMode(GL_PROJECTION);//Set projection mode and Vista size glLoadIdentity(); if (w <= h) glOrtho(-0.5 * w_width, 0.5 * w_width, -0.5 * w_height * (GLfloat)w_height / (GLfloat)w_width, 0.5 * w_height * (GLfloat)w_height / (GLfloat)w_width, -ZVALUE, ZVALUE); else glOrtho(-0.5 * w_width, 0.5 * w_width, -0.5 * w_height * (GLfloat)w_width / (GLfloat)w_height, 0.5 * w_height * (GLfloat)w_width / (GLfloat)w_height, -ZVALUE, ZVALUE); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } void keyboard(unsigned char key, int x, int y) { switch (key) { case 'w': case 'W': { my_traslate_inhomogeneous(rectangle, 4, 0, 1);//Move 1 unit in the positive direction of Y axis glutPostRedisplay(); break; } case 's': case 'S': { my_traslate_inhomogeneous(rectangle, 4, 0, -1);//Move 1 unit in the negative direction of Y axis glutPostRedisplay(); break; } case 'a': case 'A': { my_traslate_inhomogeneous(rectangle, 4, -1, 0);//Move 1 unit in the negative direction of the X-axis glutPostRedisplay(); break; } case 'd': case 'D': { my_traslate_inhomogeneous(rectangle, 4, 1, 0);//Move 1 unit in the positive direction of X axis glutPostRedisplay(); break; } case 27: exit(0); break; } } //calling function int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB|GLUT_DEPTH); glutInitWindowSize(w_width, w_height); glutInitWindowPosition(50, 50); glutCreateWindow("2"); init(); glutReshapeFunc(reshape); glutDisplayFunc(display); glutKeyboardFunc(keyboard); glutMainLoop(); return 0; }
rectangle keeps marking the red line, saying "the expression must be a pointer to the complete object type"
Compared with the code that can be run line by line, I didn't find anything wrong.
Defines a structure struct, which defines two variables int x and int y. Then there is another instance, rectangle, which requires X and y.
I reviewed the concepts of pointer and structure again. In short, I can't see any problems. Then I typed it again and found that I wrote an e less in the naming of my structure
... okay, it's okay
Now let's analyze the nonhomogeneous translation transformation
Nonhomogeneous translation transformation is a transformation that does not involve a matrix. Directly change the coordinate position of the graph to achieve the effect.
need:
1. Structure
struct my_v_inhomogeneous {float x; foat y; }
2.void()
Record add variable
void my_translate_inhomogeneous(struct my_v_inhomogeneous*polygon,int polygon_vertex_count,int tx,int ty) { for (int vIndex=0;vIndex<polygon_vertex_count;vIndex++) { polygon[vIndex].x+=tx; polygon[vIndex].y+=ty; } }
3. Keyboard or mouse interaction. (mouse is selected here)
When w is pressed, my_translate_inhomogeneous (rectangle, several vertices, x-axis distance, y-distance) will transform
my_traslate_inhomogeneous(rectangle, 4, 0, 1);// Move 1 unit in the positive direction of Y axis.
glutPostRedisplay(): marks that the current window needs to be redrawn
x and y of polygon[vIndex] will be affected, tx and ty will change, and then assigned to x and y with + =.
void keyboard(unsigned char key, int x, int y) { switch (key) { case 'w': case 'W': { my_traslate_inhomogeneous(rectangle, 4, 0, 1);//Move 1 unit in the positive direction of Y axis glutPostRedisplay(); break; } case 's': case 'S': { my_traslate_inhomogeneous(rectangle, 4, 0, -1);//Move 1 unit in the negative direction of Y axis glutPostRedisplay(); break; } case 'a': case 'A': { my_traslate_inhomogeneous(rectangle, 4, -1, 0);//Move 1 unit in the negative direction of the X-axis glutPostRedisplay(); break; } case 'd': case 'D': { my_traslate_inhomogeneous(rectangle, 4, 1, 0);//Move 1 unit in the positive direction of X axis glutPostRedisplay(); break; } case 27: exit(0); break; } }
In fact, I'm not very clear about the struct my here_ v_ What does inhomogeneous * polygon mean. but
It's my short learning experience that tells me that I can't understand it... I can't understand it even more when I'm dead. I can always understand it at another time.
4.display function.
The previous operations are to re assign x and y, but they do not involve the display above. We can't see any change yet
The x and y of this structure rectangle (suddenly realized the role of struct... Can change the x and Y corresponding to each rectangle[i])
Therefore, in the display, the changes brought by the rectangle should be displayed.
glBegin~glend doesn't explain.
Traverse each vertex of the quadrilateral,
{draw the i vertex
Draw the next vertex}
glVertex2i is a function for drawing two-dimensional graphics.
glBegin(GL_POLYGON); //GL_LINE_LOOP for (int vIndex = 0; vIndex < 3; vIndex++) { glVertex2i(rectangle[vIndex].x, rectangle[vIndex].y); glVertex2i(rectangle[vIndex + 1].x, rectangle[vIndex + 1].y); } glEnd();