• OpenGL画线画圆画多边形


    算法是midpoint drawing algorithm,谁想的我也不知道...

    画线:按l,用鼠标点两个点;

    画圆:按o,用鼠标点一个圆心拉成一个圆;

    画多边形:按p,就跟画线差不多,最后右键闭合;

    清屏:按c;

    重画:按c后按r,redraw,需要用链表保存每个图形;

    ps:在vs下运行.

      1 又修改了一下
      2 // Computer Graphics: Lab1
      3 #include <iostream>
      4 #include <stdlib.h>
      5 #include <cmath>
      6 #include <gl/glut.h>
      7 
      8 using namespace std;
      9 int height, width;
     10 static int xOrg = 0, yOrg = 0;
     11 // Max number of lines for drawing: 100
     12 const int max_line=100;
     13 // Max number of polygons for drawing: 20
     14 const int max_polygon=20;
     15 // Max number of circles for drawing: 20
     16 const int max_circle=20;
     17 
     18 
     19 struct line_structure
     20 {
     21     int x0,x1,y0,y1;
     22 };
     23 struct line_data
     24 {
     25     int x,y;
     26     line_data* next;
     27 };
     28 struct center_data
     29 {
     30     int c_x, c_y;
     31 };
     32 
     33 struct poly_point
     34 {
     35     int x;
     36     int y;
     37 }pp[max_line];
     38 
     39 line_structure line[max_line];
     40 line_data line_start[max_line];
     41 line_data polygon_start[max_polygon];
     42 line_data circle_start[max_circle];
     43 center_data center[max_circle];
     44 //line_data* lcp;
     45 line_data* temp;
     46 
     47 int points[3];
     48 
     49 int key_line=1;
     50 
     51 int num_lines=0; //这个全局变量好像有点问题,不知道为什么值会变
     52 int num_polygon=0;
     53 int num_circle=0;
     54 int count_num_line=0;
     55 
     56 bool connected=false;
     57 bool first_point=true;
     58 int count_line_points=0;
     59 int count_poly_point=0;
     60 
     61 void drawDot(int x, int y, float r, float g, float b);
     62 void Mymouse_Dot(int button, int state, int x, int y);
     63 void Myhouse_Line(int button, int state, int x, int y);
     64 void Mymouse_Polygon(int button, int state, int x, int y);
     65 void Mymouse_Circle(int button, int state, int x, int y);
     66 void drawLine1(int x0, int x1, int y0, int y1, bool xy_interchange);
     67 void drawLine2(int x0, int x1, int y0, int y1, bool xy_interchange);
     68 void drawLine3(int x0, int x1, int y0, int y1, bool xy_interchange);
     69 void drawLine4(int x0, int x1, int y0, int y1, bool xy_interchange);
     70 void drawCircle(int radius, int center_x, int center_y);
     71 void CirclePoints(int x, int y, int center_x, int center_y);
     72 void redraw();
     73 void myKeyboard(unsigned char key, int x, int y);
     74 void clear();
     75 void displayFunc(void);
     76 void DrawLines_4(int x1, int y1, int x2, int y2);
     77 
     78 void DrawLines_4(int x1, int y1, int x2, int y2) //判断画哪一种线
     79 {
     80     if(x1 >= x2)
     81     {
     82         if(y1 >= y2)
     83         {
     84             swap(x1, x2);
     85             swap(y1, y2);
     86             if((y2-y1) >= (x2-x1))            
     87                 drawLine2(x1, y1, x2, y2, 1);    
     88             else
     89                 drawLine1(x1, y1, x2, y2, 1);
     90         }
     91         else
     92         {
     93             if((y2-y1) >= (x1-x2))
     94                 drawLine3(x1, y1, x2, y2, 1);
     95             else
     96                 drawLine4(x2, y2, x1, y1, 1);
     97         }                
     98     }
     99     else
    100     {
    101         if(y2 >= y1)
    102         {
    103             if((y2-y1) <= (x2-x1))
    104                 drawLine1(x1, y1, x2, y2, 1);
    105             else
    106                 drawLine2(x1, y1, x2, y2, 1);
    107         }
    108         else
    109         {
    110             if((y1-y2) <= (x2-x1))
    111                 drawLine4(x1, y1, x2, y2, 1);
    112             else
    113                 drawLine3(x2, y2, x1, y1, 1);
    114         }
    115     }
    116     
    117     glFlush();
    118 }
    119 
    120 // Draw 8 points
    121 void CirclePoints(int x, int y, int center_x, int center_y)
    122 {
    123     drawDot(x+center_x, y+center_y, 10.0, 0.0, 0.0);
    124     drawDot(x+center_x, -y+center_y, 10.0, 0.0, 0.0);
    125     drawDot(-x+center_x, y+center_y, 10.0, 0.0, 0.0); 
    126     drawDot(-x+center_x, -y+center_y, 10.0, 0.0, 0.0); 
    127     drawDot(y+center_x, x+center_y, 10.0, 0.0, 0.0); 
    128     drawDot(y+center_x, -x+center_y, 10.0, 0.0, 0.0); 
    129     drawDot(-y+center_x, x+center_y, 10.0, 0.0, 0.0); 
    130     drawDot(-y+center_x, -x+center_y, 10.0, 0.0, 0.0); 
    131 }
    132 
    133 // Draw a circle
    134 void drawCircle(int radius, int center_x, int center_y)
    135 {
    136     cout << "Drawing Circle!!!" << endl;
    137     int x = 0; //初始值必须为0
    138     int y = radius;
    139     
    140     center_data center_point; //储存圆心
    141     center_point.c_x = xOrg;
    142     center_point.c_y = yOrg;
    143     center[num_circle] = center_point;
    144     
    145     circle_start[num_circle].x = x; //储存起点
    146     circle_start[num_circle].y = y;
    147     circle_start[num_circle].next = NULL;
    148     line_data *tmp = &circle_start[num_circle];
    149     num_circle++;
    150 
    151     int d = 1 - radius;
    152     int IncE = 3;
    153     int IncSE = -2 * radius + 5;
    154     while(x < y)
    155     {
    156         if(d < 0)
    157         {
    158             d += IncE;
    159             x++;
    160             IncE += 2;
    161             IncSE += 2;
    162         }
    163         else
    164         {
    165             d += IncSE;
    166             x++;
    167             y--;
    168             IncE += 2;
    169             IncSE += 4;
    170         }
    171         CirclePoints(x, y, center_x, center_y);
    172         
    173         line_data *add = new line_data;
    174         add->x = x;
    175         add->y = y;
    176         add->next = NULL;
    177         tmp->next = add;
    178         tmp = add;
    179     }
    180 }
    181 
    182 // Mouse control for circle drawing
    183 void Mymouse_Circle(int button, int state, int x, int y)                                 //Circle
    184 {
    185     if(num_circle > max_circle)
    186         return ;
    187     int radius = 0;
    188     if (state == GLUT_DOWN) {
    189         cout << "	button is down" << endl;
    190         if (button == GLUT_LEFT_BUTTON)
    191         {
    192             drawDot(x, y, 0.0, 10.0, 0.0); 
    193             glFlush();        
    194         }
    195         xOrg = x;
    196         yOrg = y;
    197         
    198     }
    199     else if (state == GLUT_UP) {
    200         cout << "	button is up" << endl;
    201         if (button == GLUT_LEFT_BUTTON)
    202         {
    203             drawDot(x, y, 0.0, 10.0, 0.0); 
    204             glFlush();    
    205             radius = (int)sqrt((xOrg-x)*(xOrg-x) + (yOrg-y)*(yOrg-y));
    206             drawCircle(radius, xOrg, yOrg);
    207             glFlush(); //必须要加
    208         }
    209     }
    210     cout << "		 Previous location: (" << xOrg << " , " << yOrg << ")" << endl;
    211     cout << "		 New location: (" << x << " , " << y << ")" << endl;
    212 
    213     /*
    214     cout << "x_down: " << xOrg << endl;
    215     cout << "y_down: " << yOrg << endl;
    216     cout << "x_up: " << x_up << endl;
    217     cout << "y_up: " << y_up << endl;
    218     cout << "radius: " << radius << endl;
    219     */
    220 }
    221 
    222 // Clear screen
    223 void clear()
    224 {
    225     glClearColor(0.0,0.0,0.0,0.0);
    226     glClear(GL_COLOR_BUFFER_BIT);
    227     glFlush();
    228 }
    229 
    230 // Mouse control for polygon drawing
    231 void Mymouse_Polygon(int button, int state, int x, int y)                             //Polygon
    232 {
    233     cout << count_poly_point << endl;
    234     if(num_polygon > max_polygon)
    235         return ;
    236     if (state == GLUT_DOWN) {
    237         cout << "	button is down" << endl;
    238         if (button == GLUT_LEFT_BUTTON)
    239         {
    240             drawDot(x, y, 0.0, 10.0, 0.0); 
    241             glFlush();
    242             if(count_poly_point < 1)
    243             {
    244                 polygon_start[num_polygon].x = x;
    245                 polygon_start[num_polygon].y = y;
    246                 polygon_start[num_polygon].next = NULL;
    247             
    248                 temp = &polygon_start[num_polygon];
    249 
    250                 poly_point p;
    251                 p.x = x;
    252                 p.y = height - y; //转换坐标
    253                 pp[count_poly_point] = p;
    254             }
    255             else
    256             {    
    257                 int x1 = pp[count_poly_point-1].x;
    258                 int y1 = pp[count_poly_point-1].y;
    259                 int x2 = x;
    260                 int y2 = height - y;
    261                 pp[count_poly_point].x = x2;
    262                 pp[count_poly_point].y = y2;
    263                 
    264 
    265                 DrawLines_4(x1, y1, x2, y2);
    266             }
    267             count_poly_point++;
    268         }
    269         
    270         
    271         if (button == GLUT_RIGHT_BUTTON)
    272         {
    273             int x1 = pp[0].x;
    274             int y1 = pp[0].y;
    275             int x2 = pp[count_poly_point-1].x;
    276             int y2 = pp[count_poly_point-1].y;
    277             DrawLines_4(x1, y1, x2, y2);
    278             num_polygon++;
    279             count_poly_point = 0;
    280         }
    281     }
    282 }
    283 
    284 // Redraw all objects stored 
    285 void redraw()                                                                               //Redraw
    286 {
    287     int i;
    288     line_data* rd_line;
    289     line_data* rd_polygon;
    290     line_data* rd_circle;
    291 
    292     for (i=0;i<count_num_line;i++)
    293     {
    294         rd_line=&line_start[i];
    295         drawDot(rd_line->x,rd_line->y,0,1,0);
    296         do
    297         {
    298             rd_line=rd_line->next;
    299             drawDot(rd_line->x,rd_line->y,0,1,0);
    300         } while (rd_line->next!=NULL);
    301     }
    302     
    303     for (i=0;i<num_polygon;i++)
    304     {
    305         rd_polygon=&polygon_start[i];
    306         drawDot(rd_polygon->x,rd_polygon->y,0,1,0);
    307         do
    308         {
    309             rd_polygon=rd_polygon->next;
    310             drawDot(rd_polygon->x,rd_polygon->y,0,1,0);
    311         } while (rd_polygon->next!=NULL);
    312     }
    313     
    314     for (i=0;i<num_circle;i++)
    315     {
    316         rd_circle=&circle_start[i];
    317         CirclePoints(rd_circle->x,rd_circle->y,center[i].c_x,center[i].c_y);        
    318         do
    319         {
    320             rd_circle=rd_circle->next;
    321             CirclePoints(rd_circle->x,rd_circle->y,center[i].c_x,center[i].c_y);
    322         } while (rd_circle->next!=NULL);
    323     }
    324     glFlush();
    325 }
    326 
    327 // draw a dot at location with integer coordinates (x,y), and with color (r,g,b)
    328 void drawDot(int x, int y, float r, float g, float b) 
    329 {
    330     glBegin(GL_POINTS);
    331   
    332     // set the color of dot
    333     glColor3f(r, g, b);
    334   
    335     // invert height because the opengl origin is at top-left instead of bottom-left
    336     glVertex2i(x , height - y);
    337   
    338     glEnd();
    339 }
    340 
    341 // Mouse callback function
    342 void Mymouse_Dot(int button, int state, int x, int y)                                            //Dot
    343 {
    344     if (state == GLUT_DOWN) {
    345         cout << "	button is down" << endl;
    346         if (button == GLUT_LEFT_BUTTON) {
    347             drawDot(x, y, 0.0, 10.0, 0.0);
    348             glFlush();
    349         }
    350         else if (button == GLUT_MIDDLE_BUTTON) {
    351             drawDot(x, y, 0.0, 1.0, 0.0);
    352             glFlush();
    353         }
    354         else if (button == GLUT_RIGHT_BUTTON) {
    355             drawDot(x, y, 0.0, 0.0, 1.0);
    356             glFlush();
    357         }
    358         xOrg = x;
    359         yOrg = y;
    360     }
    361     else if (state == GLUT_UP) {
    362         cout << "	button is up" << endl;
    363         if (button == GLUT_LEFT_BUTTON) {    
    364             drawDot(x, y, 0.0, 10.0, 0.0);
    365             glFlush();
    366         }
    367         else if (button == GLUT_MIDDLE_BUTTON) {
    368             drawDot(x, y, 0.0, 0.5, 0.0);
    369             glFlush();
    370         }
    371         else if (button == GLUT_RIGHT_BUTTON) {
    372             drawDot(x, y, 0.0, 0.0, 0.5);
    373             glFlush();
    374         }
    375     }
    376     cout << "		 Previous location: (" << xOrg << " , " << yOrg << ")" << endl;
    377     cout << "		 New location: (" << x << " , " << y << ")" << endl;
    378 }
    379 
    380 
    381 
    382 // Mouse control for line drawing 
    383 void Mymouse_Line(int button, int state, int x, int y)                                    //Line
    384 {
    385     if(count_num_line > max_line)
    386         return ;
    387     if (state == GLUT_DOWN) {
    388         cout << "	button is down" << endl;
    389         if (button == GLUT_LEFT_BUTTON)
    390         {
    391             drawDot(x, y, 0.0, 10.0, 0.0); 
    392             glFlush();        
    393         }
    394         xOrg = x;
    395         yOrg = height - y; //转换坐标
    396         
    397         if(count_line_points < 4)
    398         {
    399             points[count_line_points++] = xOrg;
    400             points[count_line_points++] = yOrg;
    401         }
    402         if(count_line_points == 4)
    403         {
    404             count_line_points = 0;
    405             int x1 = points[0];
    406             int y1 = points[1];
    407             int x2 = points[2];
    408             int y2 = points[3];
    409             
    410             line_start[count_num_line].x = x;
    411             line_start[count_num_line].y = y;
    412             line_start[count_num_line].next = NULL;
    413             temp = &line_start[count_num_line];
    414 
    415             DrawLines_4(x1, y1, x2, y2);
    416 
    417             count_num_line++;
    418 
    419             glFlush();
    420         }
    421         
    422     }
    423     cout << "		 Previous location: (" << xOrg << " , " << yOrg << ")" << endl;
    424     cout << "		 New location: (" << x << " , " << y << ")" << endl;
    425 }
    426 
    427 // Draw line for dx>0 and dy>0
    428 void drawLine1(int x1, int y1, int x2, int y2, bool xy_interchange) //0-45度
    429 {
    430     cout << "Drawing Line1!" << endl;
    431     int x = x1;
    432     int y = y1;    
    433 
    434     int a = y2 - y1;
    435     int b = x1 - x2;
    436     int d = 2 * a + b;
    437     int IncE = 2 * a;
    438     int IncNE = 2 * (a + b);
    439 
    440     while(x <= x2)
    441     {
    442         if(d <= 0)
    443         {
    444             x++;
    445             d += IncE;
    446         }
    447         else
    448         {
    449             x++;
    450             y++;
    451             d += IncNE;
    452         }
    453         drawDot(x, height-y, 0.0, 10.0, 0.0);
    454         
    455         line_data *add = new line_data;
    456         add->x = x;
    457         add->y = height-y;
    458         add->next = NULL;
    459         temp->next = add;
    460         temp = add;
    461     }
    462 }
    463 
    464 // Draw line for dx>0 and dy<0
    465 void drawLine2(int x1, int y1, int x2, int y2, bool xy_interchange) //45-90度
    466 {
    467     cout << "Drawing Line2!" << endl;
    468     //转换为0-45度的情况
    469     swap(x2, y2);
    470     swap(x1, y1);
    471 
    472     int x = x1;
    473     int y = y1;
    474     
    475     int a = y2 - y1;
    476     int b = x1 - x2;
    477     int d = 2 * a + b;
    478     int IncE = 2 * a;
    479     int IncNE = 2 * (a + b);
    480 
    481     while(x <= x2)
    482     {
    483         if(d <= 0)
    484         {
    485             x++;
    486             d += IncE;
    487         }
    488         else
    489         {
    490             x++;
    491             y++;
    492             d += IncNE;
    493         }
    494         drawDot(y, height-x, 0.0, 10.0, 0.0);
    495 
    496         line_data *add = new line_data;
    497         add->x = y;
    498         add->y = height-x;
    499         add->next = NULL;
    500         temp->next = add;
    501         temp = add;    
    502     }    
    503 }
    504 
    505 // Draw line for dx<0 and dy>0
    506 void drawLine3(int x1, int y1, int x2, int y2, bool xy_interchange) //90-135度
    507 {
    508     cout << "Drawing Line3!" << endl;
    509     swap(x2, y2);
    510     swap(x1, y1);
    511     y1 = -y1;
    512     y2 = -y2;
    513     int x = x1;
    514     int y = y1;
    515 
    516     int a = y2 - y1;
    517     int b = x1 - x2;
    518     int d = 2 * a + b;
    519     int IncE = 2 * a;
    520     int IncNE = 2 * (a + b);
    521 
    522     while(x <= x2)
    523     {
    524         if(d <= 0)
    525         {
    526             x++;
    527             d += IncE;
    528         }
    529         else
    530         {
    531             x++;
    532             y++;
    533             d += IncNE;
    534         }
    535         drawDot(-y, height-x, 0.0, 10.0, 0.0);
    536 
    537         line_data *add = new line_data;
    538         add->x = -y;
    539         add->y = height-x;
    540         add->next = NULL;
    541         temp->next = add;
    542         temp = add;
    543     }
    544 }
    545 
    546 // Draw line for dx<0 and dy>0
    547 void drawLine4(int x1, int y1, int x2, int y2, bool xy_interchange) //135-180度
    548 {
    549     cout << "Drawing Line4!" << endl;
    550     y1 = -y1;
    551     y2 = -y2;
    552     int x = x1;
    553     int y = y1;
    554     
    555     int a = y2 - y1;
    556     int b = x1 - x2;
    557     int d = 2 * a + b;
    558     int IncE = 2 * a;
    559     int IncNE = 2 * (a + b);
    560 
    561     while(x <= x2)
    562     {
    563         if(d <= 0)
    564         {
    565             x++;
    566             d += IncE;
    567         }
    568         else
    569         {
    570             x++;
    571             y++;
    572             d += IncNE;
    573         }
    574         drawDot(x, height+y, 0.0, 10.0, 0.0);
    575 
    576         line_data *add = new line_data;
    577         add->x = x;
    578         add->y = height+y;
    579         add->next = NULL;
    580         temp->next = add;
    581         temp = add;
    582     }
    583 }
    584 
    585 // Keyboard callback function
    586 void myKeyboard(unsigned char key, int x, int y) 
    587 {
    588     switch(key) {
    589     // Draw dots with 'd' or 'D'
    590     case 'd':
    591     case 'D':
    592         cout << "press key: " << 'd' << endl;
    593           glutMouseFunc(Mymouse_Dot);
    594           break;
    595     // Draw lines with 'l' or 'L'
    596     case 'l':
    597     case 'L':
    598         cout << "press key: " << 'l' << endl;
    599         glutMouseFunc(Mymouse_Line);
    600         break;
    601     // Draw polygons with 'p' or 'P'
    602     case 'p':
    603     case 'P':
    604         cout << "press key: " << 'p' << endl;
    605         glutMouseFunc(Mymouse_Polygon);
    606         break;
    607     // Draw circle with 'c' or 'C'
    608     case 'o':
    609     case 'O':
    610         cout << "press key: " << 'o' << endl;
    611         glutMouseFunc(Mymouse_Circle);
    612         break;
    613     // Redraw all with 'r' or 'R'
    614     case 'r':
    615     case 'R':
    616         cout << "press key: " << 'r' << endl;
    617         redraw();
    618         break;
    619     // Clear screen with 'c' or 'C'
    620     case 'c':
    621     case 'C':
    622         cout << "press key: " << 'c' << endl;
    623         clear();
    624         break;
    625     // Quit with 'q' or 'Q'
    626     case 'q':
    627     case 'Q':
    628         cout << "press key: " << 'q' << endl;
    629         exit(0);
    630         break;
    631     }
    632 }
    633 
    634 // Display function
    635 void displayFunc(void){
    636     // clear the entire window to the background color
    637     glClear(GL_COLOR_BUFFER_BIT); 
    638     glClearColor(0.0, 0.0, 0.0, 0.0); 
    639 
    640     // draw the contents!!! Iterate your object's data structure!
    641 
    642     // flush the queue to actually paint the dots on the opengl window
    643     glFlush();
    644 }
    645 
    646 // Main
    647 void main(int ac, char** av) {
    648 
    649     cout << "Hello Glut!" << endl;
    650     
    651     int winSizeX, winSizeY;
    652   
    653     if(ac == 3) {
    654     winSizeX = atoi(av[1]);
    655     winSizeY = atoi(av[2]);
    656     }
    657     else { // default window size
    658     winSizeX = 800;
    659     winSizeY = 600;
    660     }
    661 
    662     width  = winSizeX;
    663     height = winSizeY;
    664 
    665     // initialize OpenGL utility toolkit (glut)
    666     glutInit(&ac, av);
    667 
    668     // single disply and RGB color mapping
    669     glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); // set display mode
    670     glutInitWindowSize(winSizeX, winSizeY);      // set window size
    671     glutInitWindowPosition(400, 100);                // set window position on screen
    672     glutCreateWindow("Lab1 Window");       // set window title
    673   
    674     // set up the mouse and keyboard callback functions
    675     glutKeyboardFunc(myKeyboard); // register the keyboard action function
    676 
    677     // displayFunc is called whenever there is a need to redisplay the window,
    678     // e.g., when the window is exposed from under another window or when the window is de-iconified
    679     glutDisplayFunc(displayFunc); // register the redraw function
    680 
    681     // set background color
    682     glClearColor(0.0, 0.0, 0.0, 0.0);     // set the background to black
    683     glClear(GL_COLOR_BUFFER_BIT); // clear the buffer
    684 
    685     // misc setup
    686     glMatrixMode(GL_PROJECTION);  // setup coordinate system
    687     glLoadIdentity();
    688     gluOrtho2D(0, winSizeX, 0, winSizeY);
    689     glShadeModel(GL_FLAT);
    690     glFlush();
    691     glutMainLoop();
    692 }
  • 相关阅读:
    java:编写jar包加密工具,防止反编译
    Linux:CentOS-7常用命令
    MyBatis:MyBatis-Plus条件构造器EntityWrapper
    SpringBoot:SpringBoot项目的配置文件放在Jar包外加载
    机械学习导
    如何選擇最佳的 Wi-Fi 無線網路頻道,獲得最佳的傳輸速度(转载)
    解决ubuntu下filezilla登录ftp看不到中文目录和文件的问题 (转载)
    输入前几个字母,用箭头就能找出开头字母相同的历史命史
    Linux系统下使用split命令分割大文件 (转载)
    删除文件时排除特定文件 (转载)
  • 原文地址:https://www.cnblogs.com/dominjune/p/4374860.html
Copyright © 2020-2023  润新知