OpenGL走査線充填アルゴリズムの詳細


本論文の例はOpenGL走査線の充填アルゴリズムを共有しています。参考にしてください。具体的な内容は以下の通りです。
説明
最近の一連のパターン学の古典的なアルゴリズムを実現しました。授業が忙しいので、このシリーズの導出については後で書きます。しかし、コメントにはすでに十分な分析があります。
状況に応じて討論する
注意横線については特に議論が必要ですが、垂直線については特に議論する必要はありません。なぜですか?
コード

#include <iostream>
#include <GLUT/GLUT.h>
#include <map>
#include <vector>
#include <list>
#include <algorithm>
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<y1){   //      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<Line> TESTLIST;
vector<vector<Line>> con; //       (  ),             
list<Line> 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<Line>> con2;
int level = 1;
/*
     :             。           。
      【  】     ,           。
       【  】       。             。
       :  map y     ,      “    ”  
     (      )     。                 。
 */
void show_v(Line a){
 /*
     :      
 */
 cout << "(" <<a.x << "," << a.y <<")";
 cout << " (" <<a.dx<<")" << "  :"<<a.ym;
 cout << " -- "<<endl;
}
bool higher(const vector<Line> & l1, const vector<Line>& 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<Line> 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 : "<<i <<endl;
 for (int j = 0; j < con[i].size(); j++) {
  vector<Line> a = con[i];
  show_v (a[j]);
 }cout <<"================"<<endl;
 }
}
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<Line> ::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<Line> ::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<Line> 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<Line> 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<Line> 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;
}
以上が本文の全部です。皆さんの勉強に役に立つように、私たちを応援してください。