OpenGL-走査線充填アルゴリズム

20823 ワード

説明
最近の一連のグラフィック古典アルゴリズムを実現した.授業が忙しいので、このシリーズのガイドについては後で書きます.しかし、注釈には十分な分析がある.
状況を分けて討論する.
注意横線については特に議論する必要があるが、垂直線については特に議論する必要はない.なぜか考えてみましょう.
コード#コード#
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
int hmin,hmax;                                 //             
struct Line {                                    //        
    float dx,x,y,ym;                            //    K    dx x  
    Line(float x1,float y1,float x2,float y2) {
        if(y1==y2){                              //          
            this->y = y1;
            this->ym = y1;
            if(x1 < x2){
                dx = x1; x = x2;
            }else{
                dx =x2;x = x1;}
        }else if(y2//      x 
            this -> x = x2;                    //     x          (    AET  )
            this ->y = y2;                     //     y ,    
            this -> ym = y1;                  //   ym
        }else{
            this -> x = x1;
            this ->y = y1;
            this -> ym = y2;
        }
        dx = (x2-x1)/(y2-y1);
    }
};
typedef list TESTLIST;
vector<vector> con;    //       (  ),             
list AET;                    //        ,   
                                         //                       
map<int, int> mapper;          //    (y )     
int x1,y1,x2,y2;                     //           
int x0,y0;                            //        
float h_min,h_max;               //          
int flag = 1;                         //           ,    ,    。
int if_drawable = 1;              //                
int window_size=600;           //           
vector<vector> con2;
int  level = 1;
/*
     :             。           。
      【  】     ,           。
       【  】       。             。
       :  map y     ,      “    ”  
     (      )     。                 。
 */
void show_v(Line a){
    /*
         :      
     */
    cout << "(" <"," << a.y <<")";
    cout << "  (" <")" << "  :"<cout << "     --      "<bool higher(const vector & l1, const vector& l2) {
    //        line  y     ;
    //                        
    return l1[0].y < l2[0].y;//             map     
}
bool AET_lefter(const Line & l1, const Line & l2) {
    // AET   line  x     ;
    return l1.x < l2.x;//             map     
}
bool lefter(const Line & l1, const Line & l2) {
    /*
         :        line  x   dx    ;
    */
    if(l1.x < l2.x){
        return 1;
    }else if (l1.x == l2.x){
        if(l1.dx<0&&l2.dx>0)
            return 1;
        else
            return 0;
    }else
        return 0;
}
void sort_con(){
    /*
         :            
       y      ,x       x        
     */
    for (int i  = 0 ; i < con.size(); i++)
        if (con[i].size()>=2)
            sort(con[i].begin(),con[i].end(),lefter);
    for (int i = 0;i < con.size(); i++) {
        vector a;
        for (int j =0; j < con[i].size(); j++)
            a.push_back(con[i][j]);
        con2.push_back(a);                  //          ,       map       
    }
    sort(con.begin(), con.end(), higher);
}
void draw_lines(float x1,float y1,float x2,float y2){
    glBegin(GL_LINES);
    glColor3f(1.0,1.0,0.0);
    glVertex2f(x1,window_size-y1);
    glVertex2f(x2,window_size-y2);
    glEnd();
    glFlush();
}
void show_con(){
    //           
    for (int i  = 0; i  < con.size(); i++) {
        cout <<"number : "<for (int j  = 0; j  < con[i].size(); j++) {
            vector a  = con[i];
            show_v (a[j]);
        }cout <<"================"<void lines_filling(){                           //          
    if (con.empty())                           //        ,          ti
        return;
    int h_leveler = 0;                         //     
    map<int,int>::iterator iter;             //        iter
    for(h_leveler = h_min;h_leveler <= h_max;h_leveler++){//    
        int id = mapper[h_leveler];
        if (!id) {                                 //          ,              ;
            float xx = 0.0; flag = 1;        //flag           
            for(list ::iterator it=AET.begin();it!=AET.end();)
            {   if (flag%2==0) {            //    !
                    draw_lines(xx, h_leveler,it->x,h_leveler);
                    for (TESTLIST::iterator pl = AET.begin(); pl != AET.end();)
                        if (pl->ym == h_leveler)
                            AET.erase(pl++);
                        else
                            pl++;               //       for                
                    it->x = it->x +it->dx;
                }else{
                    if (it->y == it->ym) {
                        xx = x1;
                    }else{
                    xx =it->x;
                    it->x = it->x +it->dx;
                    }
                }flag++;it++;}
        }else{                                  //        ,    、  
            list ::iterator it;
            float xx = 0.0;int counter = 1;
            for(it=AET.begin();it!=AET.end();it++)
            {    Line temp= *it;
                if (counter%2==0)            //    !
                    draw_lines(xx, h_leveler,temp.x,h_leveler);
                else
                    xx =temp.x;                 //            
                counter++;
            }
            for (TESTLIST::iterator it = AET.begin(); it != AET.end();)
                if (it->ym == h_leveler)
                    AET.erase(it++);
                else
                    it++;                         //       
            for (int i =0 ; i < con2[id-1].size(); i++)
                if (con2[id-1][i].y == con2[id-1][i].ym)
                    continue;                   //              
                else
                    AET.push_back(con2[id-1][i]);
            AET.sort(AET_lefter);          //            
        }}}
void InitEnvironment()                     //          
{   glClearColor(0.0,0.0,0.0,0);
    glClear(GL_COLOR_BUFFER_BIT);
    glPointSize(7);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluOrtho2D(0,window_size,0,window_size);
}
void myDisplay(void)
{   glClear(GL_COLOR_BUFFER_BIT);
    glFlush();
}
void OnMouse(int button,int state,int x,int y)
/*
     :         
           。    、      
 */
{if(button==GLUT_LEFT_BUTTON&&state==GLUT_DOWN&&if_drawable)
    {if (flag ==1 &&if_drawable) {
            glColor3f(1,0,0);
            glBegin(GL_POINTS);
            glVertex2f(x,window_size-y);
            x0 = x;y0 =y;
            x1 = x;y1 = y;
            h_min = y0;
            h_max = y0;
            glEnd();
            glFlush();
            flag++;
        }else{
            glColor3f(1,0,0);
            glBegin(GL_POINTS);
            glVertex2f(x,window_size-y);
            glEnd();
            x2 = x;y2 = y;
            glBegin(GL_LINES);
            glColor3f(1.0,0.0,0.0);
            glVertex2f(x1,window_size-y1);
            glVertex2f(x2,window_size-y2);
            if (y1 !=y2) {
                Line a(x1,y1,x2,y2);
            int r_y = min (y1,y2);
                if (y1 < h_min)
                    h_min = y1;
                if (y2 < h_min)
                    h_min = y2;
                if (y1 > h_max)
                    h_max = y1;
                if (y2 >h_max)
                    h_max = y2;
            int pos = mapper[r_y];
            if (pos==0) {           //           
                mapper[r_y] = level++;
                vector lines;
                lines.push_back(a);
                con.push_back(lines);}
            else
                con[pos-1].push_back(a);
            }
            x1 = x2; y1 = y2;
            glEnd();
            glFlush();
        }
    }
    if(button==GLUT_RIGHT_BUTTON&&state==GLUT_DOWN&&if_drawable)
    {   //    
        glColor3f(1,0,0);
        glBegin(GL_POINTS);
        glVertex2f(x,window_size-y);
        glEnd();
        x2 = x;y2 = y;
        glBegin(GL_LINES);
        glColor3f(1.0,0.0,0.0);
        glVertex2f(x1,window_size-y1);
        glVertex2f(x2,window_size-y2);
        Line a(x1,y1,x2,y2);
        int r_y = min (y1,y2);
        int pos = mapper[r_y];
        if (pos==0) {           //           
            mapper[r_y] = level++;
            vector lines;
            lines.push_back(a);
            con.push_back(lines);}
        else
            con[pos-1].push_back(a);
        glEnd();
        glFlush();
        glBegin(GL_LINES);
        glColor3f(1.0,0.0,0.0);
        glVertex2f(x0,window_size-y0);
        glVertex2f(x2,window_size-y2);
        glEnd();
        glFlush();
        Line aa(x0,y0,x2,y2);
        r_y = min (y0,y2);
        pos = mapper[r_y];
        if (pos==0) {           //           
            mapper[r_y] = level++;
            vector lines;
            lines.push_back(aa);
            con.push_back(lines);}
        else
            con[pos-1].push_back(aa);
        sort_con();
        lines_filling();
        if_drawable = 0;
    }
}

int main(int argc, char *argv[])
{   glutInit(&argc, argv);   //   GLUT
    glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
    glutInitWindowPosition(300, 100);
    glutInitWindowSize(window_size, window_size);
    glutCreateWindow("hw2_filling_line");
    InitEnvironment();   //   
    glutMouseFunc(&OnMouse);  //      
    glutDisplayFunc(&myDisplay);   //    
    glutMainLoop();    //    ,            
    return 0;
}