OpenGL走査線充填アルゴリズムの詳細
8993 ワード
本論文の例は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;
}
以上が本文の全部です。皆さんの勉強に役に立つように、私たちを応援してください。