码迷,mamicode.com
首页 > 其他好文 > 详细

OpenGL多边形变换和裁剪

时间:2015-05-22 23:50:04      阅读:316      评论:0      收藏:0      [点我收藏+]

标签:

  1 // Computer Graphics: HW2
  2 // 3D Rendering pipeline: 
  3 // Space Transformation and Polygon clipping use Sutherland-Hodgman Algorithm
  4   5 
  6 #include <iostream>
  7 #include <string>
  8 #include <cstdlib>
  9 #include <cmath>
 10 #include <cstdio>
 11 #include <vector>
 12 #include <gl/glut.h>
 13 #include <iomanip>
 14 
 15 using namespace std;
 16 
 17 const int dimension = 3;
 18 const double PI = acos(-1);
 19 const double eps = 0.0000001;
 20 
 21 struct mat {                    //定义矩阵用作变换操作 
 22     float m[3][3];
 23     mat()
 24     {
 25         memset(m, 0, sizeof(m));    
 26     }
 27     void reset_mat()
 28     {
 29         for(int i=0; i<dimension; i++)
 30             for(int j=0; j<dimension; j++)
 31             {
 32                 if(i == j)    m[i][j] = 1;
 33                 else        m[i][j] = 0;
 34             }        
 35     }
 36 };
 37 
 38 mat T, S, R, TM, WVM, M;
 39 
 40 mat operator * (mat a, mat b)        //重载*号实现矩阵乘法 
 41 {
 42     mat c;
 43     for(int i=0; i<dimension; i++)
 44         for(int j=0; j<dimension; j++)
 45             for(int k=0; k<dimension; k++)
 46                 c.m[i][j] += (a.m[i][k]*b.m[k][j]);        
 47     return c;
 48 }
 49 
 50 struct square_point {        //在HP坐标上定义正方形的点 
 51     float x;
 52     float y;
 53     float hp;
 54     square_point(){ x=0; y=0; hp=1;}
 55     square_point(float _x, float _y, float _hp=1){ x=_x; y=_y; }
 56 };
 57 vector <square_point> squa_trans[101], squa_view[101]; //储存变换数组,储存显示数组,用二维数组不行的啊
 58 square_point squa_clip[101];    //储存clipping数组的点 
 59 int squa_clip_cnt=0;        //计算clipping获得点的个数 
 60 int squa_num=0;                //计算正方形个数 
 61 int squa_view_num=0;        //计算显示的正方形个数 
 62 
 63 struct tri_point {        //在HP坐标上定义三角形的点 
 64     float x;
 65     float y;
 66     float hp;
 67     tri_point(){ x=0; y=0; hp=1;}
 68     tri_point(float _x, float _y, float _hp=1){ x=_x; y=_y; }
 69 };
 70 vector <tri_point> tri_trans[101], tri_view[101];
 71 tri_point tri_clip[101];
 72 int tri_clip_cnt=0;
 73 int tri_num=0;
 74 int tri_view_num=0;
 75 
 76 
 77 int cc=0;
 78 string status="none";
 79 int view_num=0;
 80 bool view_flag=0;
 81 float Xwmin, Xwmax, Ywmin, Ywmax, Xvmin, Xvmax, Yvmin, Yvmax;    //viewport的坐标 
 82 int height, width;
 83 void displayFunc(void);
 84 void ReadInput(bool& IsExit);
 85 void scale(float sx, float sy);        //放大缩小变换 
 86 void rotate(float degree);            //旋转变换
 87 void translate(float tx, float ty);        //平移变换
 88 void reset();
 89 void square();        //创建正方形,并做transformation变换 
 90 void triangle();    //创建三角形,并做transformation变换  
 91 void view(float Xwmin, float Xwmax, float Ywmin, float Ywmax, float Xvmin, float Xvmax, float Yvmin, float Yvmax); //投影到viewport 
 92 void clearData();
 93 void clearScreen();
 94 void initial();        //初始化各个变换矩阵,正方形和三角形个数,以及存储点的向量数组 
 95 void DrawWindow();    //画出viewport的框框 
 96 void square_clip_judge_1(int i, int size);    //1-st pass in Polygon Clipping
 97 void square_clip_judge_2(int i, int size);    //2-nd pass in Polygon Clipping
 98 void square_clip_judge_3(int i, int size);    //3-rd pass in Polygon Clipping
 99 void square_clip_judge_4(int i, int size);    //4-th pass in Polygon Clipping
100 void square_clipping(int i);        //调用4种clipping 
101 void square_save(int i);            //调每次clipping后保存顶点 
102 void square_drawing();                //画正方形,调用之前的DrawLine等画线函数 
103 
104 void tri_clip_judge_1(int i, int size);    //三角形的函数和正方形的定义方式都一样的 
105 void tri_clip_judge_2(int i, int size);
106 void tri_clip_judge_3(int i, int size);
107 void tri_clip_judge_4(int i, int size);
108 void tri_clipping(int i);
109 void tri_save(int i);
110 void tri_drawing();
111 
112 void drawDot(int x, int y, float r, float g, float b);    //hw1中已经实现的函数 
113 void drawLine1(int x0, int x1, int y0, int y1, bool xy_interchange);
114 void drawLine2(int x0, int x1, int y0, int y1, bool xy_interchange);
115 void drawLine3(int x0, int x1, int y0, int y1, bool xy_interchange);
116 void drawLine4(int x0, int x1, int y0, int y1, bool xy_interchange);
117 void DrawLines_4(int x1, int y1, int x2, int y2);
118 
119 void DrawWindow()
120 {
121     DrawLines_4(Xvmin, Yvmin, Xvmax, Yvmin);
122     DrawLines_4(Xvmax, Yvmin, Xvmax, Yvmax);
123     DrawLines_4(Xvmax, Yvmax, Xvmin, Yvmax);
124     DrawLines_4(Xvmin, Yvmax, Xvmin, Yvmin);
125 }
126 /*
127 bool judge_in(int x, int y)
128 {
129     if(x > Xvmin && x < Xvmax && y > Yvmin && y < Yvmax)
130             return 1;
131     return 0;
132 }*/
133 ////////////////////////////////////////////////////////////////////////////////square
134 void square_save(int i)
135 {
136     //cout << "squa_view_num : " << squa_view_num << endl;
137     //cout << "squa_clip_cnt : " << squa_clip_cnt << endl;
138 
139     squa_view_num = squa_clip_cnt;
140     for(int j=0; j<squa_view_num; j++)
141         squa_view[i][j] = squa_clip[j];
142     squa_clip_cnt=0;
143 }
144 void square_clip_judge_1(int i, int size)
145 {
146     if(size == 0)
147         return ;
148     square_point s, p, t;
149     for(int j=0; j<size-1; j++)
150     {
151         s.x = squa_view[i][j].x; s.y = squa_view[i][j].y;
152         p.x = squa_view[i][j+1].x; p.y = squa_view[i][j+1].y;
153         
154         t.x = Xvmin;    
155         t.y = (p.y-s.y)*(t.x-s.x)/(p.x-s.x)+s.y; 
156         
157         if(s.x >= Xvmin && p.x >= Xvmin)            squa_clip[squa_clip_cnt++] = p;
158         else if(s.x > Xvmin && p.x < Xvmin)        squa_clip[squa_clip_cnt++] = t;
159         else if(s.x < Xvmin && p.x < Xvmin); 
160         else if(s.x < Xvmin && p.x > Xvmin)        {squa_clip[squa_clip_cnt++] = t;squa_clip[squa_clip_cnt++] = p; }
161     }
162     
163     s.x = squa_view[i][size-1].x;    s.y = squa_view[i][size-1].y;
164     p.x = squa_view[i][0].x;    p.y = squa_view[i][0].y;
165     
166     t.x = Xvmin;    
167     t.y = (p.y-s.y)/(p.x-s.x)*(t.x-s.x)+s.y;
168 
169     if(s.x >= Xvmin && p.x >= Xvmin)            squa_clip[squa_clip_cnt++] = p;
170     else if(s.x > Xvmin && p.x < Xvmin)        squa_clip[squa_clip_cnt++] = t;
171     else if(s.x < Xvmin && p.x < Xvmin); 
172     else if(s.x < Xvmin && p.x > Xvmin)        {squa_clip[squa_clip_cnt++] = t;squa_clip[squa_clip_cnt++] = p; }
173     
174     square_save(i);
175     
176 }
177 void square_clip_judge_2(int i, int size)
178 {    
179     if(size == 0)
180         return ;
181     square_point s, p, t;
182     for(int j=0; j<size-1; j++)
183     {
184         s.x = squa_view[i][j].x; s.y = squa_view[i][j].y;
185         p.x = squa_view[i][j+1].x; p.y = squa_view[i][j+1].y;
186 
187         t.y = Yvmin;    
188         t.x = (t.y-s.y)/(p.y-s.y)*(p.x-s.x)+s.x; 
189     
190         if(s.y >= Yvmin && p.y >= Yvmin)            squa_clip[squa_clip_cnt++] = p;
191         else if(s.y > Yvmin && p.y < Yvmin)        squa_clip[squa_clip_cnt++] = t;
192         else if(s.y < Yvmin && p.y < Yvmin); 
193         else if(s.y < Yvmin && p.y > Yvmin)        { squa_clip[squa_clip_cnt++] = t;squa_clip[squa_clip_cnt++] = p; }
194     }
195 
196     s.x = squa_view[i][size-1].x;    s.y = squa_view[i][size-1].y;
197     p.x = squa_view[i][0].x;    p.y = squa_view[i][0].y;
198     
199     t.y = Yvmin;        
200     t.x = (t.y-s.y)/(p.y-s.y)*(p.x-s.x)+s.x;
201     
202     if(s.y >= Yvmin && p.y >= Yvmin)            squa_clip[squa_clip_cnt++] = p;
203     else if(s.y > Yvmin && p.y < Yvmin)        squa_clip[squa_clip_cnt++] = t;
204     else if(s.y < Yvmin && p.y < Yvmin); 
205     else if(s.y < Yvmin && p.y > Yvmin)        { squa_clip[squa_clip_cnt++] = t;squa_clip[squa_clip_cnt++] = p; }
206     
207     square_save(i);
208     
209 }
210 void square_clip_judge_3(int i, int size)
211 {
212     if(size == 0)
213         return ;
214     square_point s, p, t;
215     for(int j=0; j<size-1; j++)
216     {
217         s.x = squa_view[i][j].x; s.y = squa_view[i][j].y;
218         p.x = squa_view[i][j+1].x; p.y = squa_view[i][j+1].y;
219         
220         t.x = Xvmax;    
221         //if(abs(p.x-s.x) > eps)
222             t.y = (p.y-s.y)*(t.x-s.x)/(p.x-s.x)+s.y;
223         
224         if(s.x <= Xvmax && p.x <= Xvmax)            squa_clip[squa_clip_cnt++] = p;
225         else if(s.x < Xvmax && p.x > Xvmax)        squa_clip[squa_clip_cnt++] = t;
226         else if(s.x > Xvmax && p.x > Xvmax); 
227         else if(s.x > Xvmax && p.x < Xvmax)        { squa_clip[squa_clip_cnt++] = t;squa_clip[squa_clip_cnt++] = p; }
228     }
229     s.x = squa_view[i][size-1].x;    s.y = squa_view[i][size-1].y;
230     p.x = squa_view[i][0].x;    p.y = squa_view[i][0].y;
231     t.x = Xvmax;    
232     //if(abs(p.x-s.x) > eps) 
233         t.y = (p.y-s.y)/(p.x-s.x)*(t.x-s.x)+s.y;
234     
235     if(s.x <= Xvmax && p.x <= Xvmax)            squa_clip[squa_clip_cnt++] = p;
236     else if(s.x < Xvmax && p.x > Xvmax)        squa_clip[squa_clip_cnt++] = t;
237     else if(s.x > Xvmax && p.x > Xvmax); 
238     else if(s.x > Xvmax && p.x < Xvmax)        { squa_clip[squa_clip_cnt++] = t;squa_clip[squa_clip_cnt++] = p; }
239 
240     square_save(i);
241     
242 }
243 void square_clip_judge_4(int i, int size)
244 {
245     if(size == 0)
246         return ;
247     square_point s, p, t;
248     for(int j=0; j<size-1; j++)
249     {
250         s.x = squa_view[i][j].x; s.y = squa_view[i][j].y;
251         p.x = squa_view[i][j+1].x; p.y = squa_view[i][j+1].y;
252         
253         t.y = Yvmax;    
254         t.x = (t.y-s.y)/(p.y-s.y)*(p.x-s.x)+s.x;
255         
256     
257         if(s.y <= Yvmax && p.y <= Yvmax)            squa_clip[squa_clip_cnt++] = p;
258         else if(s.y < Yvmax && p.y > Yvmax)        squa_clip[squa_clip_cnt++] = t;
259         else if(s.y > Yvmax && p.y > Yvmax); 
260         else if(s.y > Yvmax && p.y < Yvmax)        { squa_clip[squa_clip_cnt++] = t;squa_clip[squa_clip_cnt++] = p; }
261     }
262     s.x = squa_view[i][size-1].x;    s.y = squa_view[i][size-1].y;
263     p.x = squa_view[i][0].x;    p.y = squa_view[i][0].y;
264     
265     t.y = Yvmax;    
266     t.x = (t.y-s.y)/(p.y-s.y)*(p.x-s.x)+s.x;
267     
268     if(s.y <= Yvmax && p.y <= Yvmax)            squa_clip[squa_clip_cnt++] = p;
269     else if(s.y < Yvmax && p.y > Yvmax)        squa_clip[squa_clip_cnt++] = t;
270     else if(s.y > Yvmax && p.y > Yvmax); 
271     else if(s.y > Yvmax && p.y < Yvmax)        { squa_clip[squa_clip_cnt++] = t;squa_clip[squa_clip_cnt++] = p; }
272 
273     square_save(i);
274     
275 }
276 void square_clipping(int i)
277 {
278     square_clip_judge_1(i, squa_view_num);
279     square_clip_judge_2(i, squa_view_num);    
280     square_clip_judge_3(i, squa_view_num);    
281     square_clip_judge_4(i, squa_view_num);
282 }
283 void square_drawing(int i, int size)
284 {
285     DrawLines_4(squa_view[i][size-1].x, squa_view[i][size-1].y, squa_view[i][0].x, squa_view[i][0].y);
286     for(int j=0; j<size-1; j++)
287         DrawLines_4(squa_view[i][j].x, squa_view[i][j].y, squa_view[i][j+1].x, squa_view[i][j+1].y);
288 }
289 ///////////////////////////////////////////////////////////////////////////////////////////////////triangle
290 void tri_clip_judge_1(int i, int size)
291 {
292     if(size == 0)
293         return ;
294     tri_point s, p, t;
295     for(int j=0; j<size-1; j++)
296     {
297         s.x = tri_view[i][j].x; s.y = tri_view[i][j].y;
298         p.x = tri_view[i][j+1].x; p.y = tri_view[i][j+1].y;
299         
300         t.x = Xvmin;    
301         t.y = (p.y-s.y)*(t.x-s.x)/(p.x-s.x)+s.y; 
302         
303         if(s.x >= Xvmin && p.x >= Xvmin)            tri_clip[tri_clip_cnt++] = p;
304         else if(s.x > Xvmin && p.x < Xvmin)        tri_clip[tri_clip_cnt++] = t;
305         else if(s.x < Xvmin && p.x < Xvmin); 
306         else if(s.x < Xvmin && p.x > Xvmin)        { tri_clip[tri_clip_cnt++] = t; tri_clip[tri_clip_cnt++] = p; }
307     }
308     
309     s.x = tri_view[i][size-1].x;    s.y = tri_view[i][size-1].y;
310     p.x = tri_view[i][0].x;    p.y = tri_view[i][0].y;
311     
312     t.x = Xvmin;    
313     t.y = (p.y-s.y)/(p.x-s.x)*(t.x-s.x)+s.y;
314     
315     if(s.x >= Xvmin && p.x >= Xvmin)            tri_clip[tri_clip_cnt++] = p;
316     else if(s.x > Xvmin && p.x < Xvmin)        tri_clip[tri_clip_cnt++] = t;
317     else if(s.x < Xvmin && p.x < Xvmin); 
318     else if(s.x < Xvmin && p.x > Xvmin)        { tri_clip[tri_clip_cnt++] = t; tri_clip[tri_clip_cnt++] = p; }
319     
320     tri_save(i);
321 }
322 void tri_clip_judge_2(int i, int size)
323 {
324     if(size == 0)
325         return ;
326     tri_point s, p, t;
327     for(int j=0; j<size-1; j++)
328     {
329         s.x = tri_view[i][j].x; s.y = tri_view[i][j].y;
330         p.x = tri_view[i][j+1].x; p.y = tri_view[i][j+1].y;
331 
332         t.y = Yvmin;    
333         t.x = (t.y-s.y)/(p.y-s.y)*(p.x-s.x)+s.x; 
334     
335         if(s.y >= Yvmin && p.y >= Yvmin)            tri_clip[tri_clip_cnt++] = p;
336         else if(s.y > Yvmin && p.y < Yvmin)        tri_clip[tri_clip_cnt++] = t;
337         else if(s.y < Yvmin && p.y < Yvmin); 
338         else if(s.y < Yvmin && p.y > Yvmin)        { tri_clip[tri_clip_cnt++] = t;tri_clip[tri_clip_cnt++] = p; }
339     }
340 
341     s.x = tri_view[i][size-1].x;    s.y = tri_view[i][size-1].y;
342     p.x = tri_view[i][0].x;    p.y = tri_view[i][0].y;
343     
344     t.y = Yvmin;    
345     t.x = (t.y-s.y)/(p.y-s.y)*(p.x-s.x)+s.x;
346     
347     if(s.y >= Yvmin && p.y >= Yvmin)            tri_clip[tri_clip_cnt++] = p;
348     else if(s.y > Yvmin && p.y < Yvmin)        tri_clip[tri_clip_cnt++] = t;
349     else if(s.y < Yvmin && p.y < Yvmin); 
350     else if(s.y < Yvmin && p.y > Yvmin)        { tri_clip[tri_clip_cnt++] = t;tri_clip[tri_clip_cnt++] = p; }
351     
352     tri_save(i);
353 }
354 void tri_clip_judge_3(int i, int size)
355 {
356     if(size == 0)
357         return ;
358     tri_point s, p, t;
359     for(int j=0; j<size-1; j++)
360     {
361         s.x = tri_view[i][j].x; s.y = tri_view[i][j].y;
362         p.x = tri_view[i][j+1].x; p.y = tri_view[i][j+1].y;
363         
364         t.x = Xvmax;    
365         //if(abs(p.x-s.x) > eps)
366             t.y = (p.y-s.y)*(t.x-s.x)/(p.x-s.x)+s.y;
367 
368         if(s.x <= Xvmax && p.x <= Xvmax)            tri_clip[tri_clip_cnt++] = p;
369         else if(s.x < Xvmax && p.x > Xvmax)        tri_clip[tri_clip_cnt++] = t;
370         else if(s.x > Xvmax && p.x > Xvmax); 
371         else if(s.x > Xvmax && p.x < Xvmax)        { tri_clip[tri_clip_cnt++] = t;tri_clip[tri_clip_cnt++] = p; }
372     }
373     s.x = tri_view[i][size-1].x;    s.y = tri_view[i][size-1].y;
374     p.x = tri_view[i][0].x;    p.y = tri_view[i][0].y;
375     t.x = Xvmax;    
376     //if(abs(p.x-s.x) > eps) 
377         t.y = (p.y-s.y)/(p.x-s.x)*(t.x-s.x)+s.y;
378     
379     if(s.x <= Xvmax && p.x <= Xvmax)            tri_clip[tri_clip_cnt++] = p;
380     else if(s.x < Xvmax && p.x > Xvmax)        tri_clip[tri_clip_cnt++] = t;
381     else if(s.x > Xvmax && p.x > Xvmax); 
382     else if(s.x > Xvmax && p.x < Xvmax)        { tri_clip[tri_clip_cnt++] = t;tri_clip[tri_clip_cnt++] = p; }
383 
384     tri_save(i);
385 }
386 void tri_clip_judge_4(int i, int size)
387 {
388     if(size == 0)
389         return ;
390     tri_point s, p, t;
391     for(int j=0; j<size-1; j++)
392     {
393         s.x = tri_view[i][j].x; s.y = tri_view[i][j].y;
394         p.x = tri_view[i][j+1].x; p.y = tri_view[i][j+1].y;
395         
396         t.y = Yvmax;    
397         t.x = (t.y-s.y)/(p.y-s.y)*(p.x-s.x)+s.x;
398     
399         if(s.y <= Yvmax && p.y <= Yvmax)            tri_clip[tri_clip_cnt++] = p;
400         else if(s.y < Yvmax && p.y > Yvmax)        tri_clip[tri_clip_cnt++] = t;
401         else if(s.y > Yvmax && p.y > Yvmax); 
402         else if(s.y > Yvmax && p.y < Yvmax)        { tri_clip[tri_clip_cnt++] = t;tri_clip[tri_clip_cnt++] = p; }
403     }
404     s.x = tri_view[i][size-1].x;    s.y = tri_view[i][size-1].y;
405     p.x = tri_view[i][0].x;    p.y = tri_view[i][0].y;
406     
407     t.y = Yvmax;    
408     t.x = (t.y-s.y)/(p.y-s.y)*(p.x-s.x)+s.x;
409     
410     if(s.y <= Yvmax && p.y <= Yvmax)            tri_clip[tri_clip_cnt++] = p;
411     else if(s.y < Yvmax && p.y > Yvmax)        tri_clip[tri_clip_cnt++] = t;
412     else if(s.y > Yvmax && p.y > Yvmax); 
413     else if(s.y > Yvmax && p.y < Yvmax)        { tri_clip[tri_clip_cnt++] = t;tri_clip[tri_clip_cnt++] = p; }
414 
415     tri_save(i);
416 }
417 void tri_clipping(int i)
418 {
419     tri_clip_judge_1(i, tri_view_num);
420     tri_clip_judge_2(i, tri_view_num);    
421     tri_clip_judge_3(i, tri_view_num);    
422     tri_clip_judge_4(i, tri_view_num);
423 }
424 void tri_save(int i)
425 {
426     tri_view_num = tri_clip_cnt;
427     for(int j=0; j<tri_view_num; j++)
428         tri_view[i][j] = tri_clip[j];
429     tri_clip_cnt=0;
430 }
431 void tri_drawing(int i, int size)
432 {
433     DrawLines_4(tri_view[i][size-1].x, tri_view[i][size-1].y, tri_view[i][0].x, tri_view[i][0].y);
434     for(int j=0; j<size-1; j++)
435         DrawLines_4(tri_view[i][j].x, tri_view[i][j].y, tri_view[i][j+1].x, tri_view[i][j+1].y);
436 }
437 void print(mat M)
438 {
439     for(int i=0; i<dimension; i++)
440     {
441         for(int j=0; j<dimension; j++)
442             printf("%.2lf ", M.m[i][j]);
443         printf("\n");
444     }
445     printf("\n");
446 }
447 void reset()
448 {
449     TM.reset_mat(); 
450     WVM.reset_mat();
451 }
452 void scale(float sx, float sy)
453 {
454     S.m[0][0] = sx; S.m[1][1] = sy;
455     TM = S * TM;
456     print(TM);
457 }
458 void rotate(float degree)
459 {
460     degree = degree * PI / 180.0;
461     R.m[0][0] = cos(degree); R.m[1][1] = cos(degree);
462     R.m[0][1] = -sin(degree); R.m[1][0] = sin(degree);
463     TM = R * TM;
464     print(TM);
465 }
466 void translate(float tx, float ty)
467 {
468     T.m[0][2] = tx; T.m[1][2] = ty;
469     TM =  T * TM;
470     print(TM);
471 }
472 void square()
473 {    
474     square_point s0(-1, -1); squa_trans[squa_num].push_back(s0); squa_view[squa_num].push_back(s0);
475     square_point s1(1, -1);  squa_trans[squa_num].push_back(s1); squa_view[squa_num].push_back(s1);
476     square_point s2(1, 1);   squa_trans[squa_num].push_back(s2); squa_view[squa_num].push_back(s2);
477     square_point s3(-1, 1);  squa_trans[squa_num].push_back(s3); squa_view[squa_num].push_back(s3);
478     
479     for(int j=0; j<squa_trans[squa_num].size(); j++)
480     {
481         float sx = TM.m[0][0] * squa_trans[squa_num][j].x + TM.m[0][1] * squa_trans[squa_num][j].y + TM.m[0][2];
482         float sy = TM.m[1][0] * squa_trans[squa_num][j].x + TM.m[1][1] * squa_trans[squa_num][j].y + TM.m[1][2];
483         squa_trans[squa_num][j].x = sx;
484         squa_trans[squa_num][j].y = sy;
485     }
486     squa_num++;;
487 }
488 void triangle()
489 {
490     tri_point t0(-1, -1); tri_trans[tri_num].push_back(t0); tri_view[tri_num].push_back(t0);
491     tri_point t1(1, -1);  tri_trans[tri_num].push_back(t1); tri_view[tri_num].push_back(t1);
492     tri_point t2(0, 1);   tri_trans[tri_num].push_back(t2); tri_view[tri_num].push_back(t2);
493     
494     for(int j=0; j<3; j++)
495     {
496         float tx = TM.m[0][0] * tri_trans[tri_num][j].x + TM.m[0][1] * tri_trans[tri_num][j].y + TM.m[0][2];
497         float ty = TM.m[1][0] * tri_trans[tri_num][j].x + TM.m[1][1] * tri_trans[tri_num][j].y + TM.m[1][2];
498         tri_trans[tri_num][j].x = tx;
499         tri_trans[tri_num][j].y = ty;
500     }
501     tri_num++;
502 }
503 
504 void view(float Xwmin, float Xwmax, float Ywmin, float Ywmax, float Xvmin, float Xvmax, float Yvmin, float Yvmax)
505 {
506     status="view";
507     DrawWindow();
508     //view_flag=0;
509     WVM.reset_mat();
510     TM.reset_mat();
511     translate(-Xwmin, -Ywmin);    
512     WVM = T * WVM;    
513     scale((Xvmax-Xvmin)/(Xwmax-Xwmin), (Yvmax-Yvmin)/(Ywmax-Ywmin));
514     WVM = S * WVM;    
515     translate(Xvmin, Yvmin);    
516     WVM = T * WVM;    
517     
518     status="square";
519     for(int i=0; i<squa_num; i++)
520     {
521         squa_view_num=4;
522         for(int j=0; j<squa_trans[i].size(); j++)
523         {
524             float sx = WVM.m[0][0] * squa_trans[i][j].x + WVM.m[0][1] * squa_trans[i][j].y + WVM.m[0][2];  //必须有中间变量
525             float sy = WVM.m[1][0] * squa_trans[i][j].x + WVM.m[1][1] * squa_trans[i][j].y + WVM.m[1][2];
526             squa_view[i][j].x = sx;        //储存view的数组必须和储存变换数组的不同
527             squa_view[i][j].y = sy;        
528         }
529         square_clipping(i);
530         if(squa_view_num == 0)
531             continue;
532         square_drawing(i, squa_view_num);
533     }
534     cout << "squa_num : " << squa_num << endl;
535     
536     status="triangle";
537     for(int i=0; i<tri_num; i++)
538     {
539         tri_view_num=3;
540         for(int j=0; j<tri_trans[i].size(); j++)
541         {
542             float sx = WVM.m[0][0] * tri_trans[i][j].x + WVM.m[0][1] * tri_trans[i][j].y + WVM.m[0][2];
543             float sy = WVM.m[1][0] * tri_trans[i][j].x + WVM.m[1][1] * tri_trans[i][j].y + WVM.m[1][2];            
544             tri_view[i][j].x = sx;
545             tri_view[i][j].y = sy;
546         }
547         tri_clipping(i);
548         if(tri_view_num == 0)
549             continue;
550         tri_drawing(i, tri_view_num);
551     }
552     cout << "tri_num : " << tri_num << endl;
553     
554     status ="none";
555     
556 }
557 void clearData()
558 {
559     
560 }
561 void clearScreen()
562 {
563     
564 }
565 void initial()
566 {
567     T.reset_mat(); S.reset_mat(); R.reset_mat(); TM.reset_mat(); WVM.reset_mat(); M.reset_mat();
568     squa_num=0;
569     tri_num=0;
570     squa_view_num=4;
571     square_point clr;
572     tri_point clear;
573     for(int i=0; i<101; i++)
574         for(int j=0; j<101; j++)
575         {
576             squa_view[i].push_back(clr);
577             tri_view[i].push_back(clear);
578         }
579             
580 
581 }
582 
583 void myKeyboard(unsigned char key, int x, int y) 
584 {
585     cout << "KEYYYY" << endl;
586     switch(key) {
587     // Draw dots with ‘d‘ or ‘D‘
588     case q:
589     case Q:
590         //glutMouseFunc(Mymouse);
591           exit(0);
592           break;
593     }
594 }
595 void ReadInput(bool& IsExit)
596 {
597     float sx,sy,degree,tx,ty;
598     string command,comment;
599     cin>>command;
600     if (command=="scale")
601     {
602         cout<<command<<endl;
603         cin>>sx;
604         cin>>sy;
605         scale(sx,sy);    
606     }
607     else if (command=="rotate")
608     {
609         cout<<command<<endl;
610         cin>>degree;
611         rotate(degree);    
612     }
613     else if (command=="translate")
614     {
615         cout<<command<<endl;
616         cin>>tx;
617         cin>>ty;
618         translate(tx,ty);    
619     }
620     else if (command=="reset")
621     {
622         cout<<command<<endl;
623         reset();
624     }
625     else if (command=="square")
626     {
627         cout<<command<<endl;
628         square();
629     }
630     else if (command=="triangle")
631     {
632         cout<<command<<endl;
633         triangle();
634     }
635     else if (command=="view")
636     {
637         cout<<command<<endl;
638         cin >> Xwmin >> Xwmax >> Ywmin >> Ywmax >> Xvmin >> Xvmax >> Yvmin >> Yvmax;
639         view(Xwmin, Xwmax, Ywmin, Ywmax, Xvmin, Xvmax, Yvmin, Yvmax);
640     }
641     else if (command=="clearData")
642     {
643         cout<<command<<endl;
644         clearData();
645     }
646     else if (command=="clearScreen")
647     {
648         cout<<command<<endl;
649         cout<<"Screen is cleared"<<endl;
650         clearScreen();    
651     }
652     else if (command=="end")
653     {
654         cout<<command<<endl;
655         IsExit=true;
656         //exit(0);
657     }
658     else if (command=="#")
659     {
660         getline(cin, comment);
661     }
662 }
663 
664 
665 // Display function
666 void displayFunc(void){
667   
668   freopen("hw2.in", "r", stdin);
669   bool IsExit;
670   IsExit=false;
671   // clear the entire window to the background color
672   glClear(GL_COLOR_BUFFER_BIT);
673   while (!IsExit)
674   {
675     glClearColor(0.0, 0.0, 0.0, 0.0); 
676 //    redraw();
677   // draw the contents!!! Iterate your object‘s data structure!
678   // flush the queue to actually paint the dots on the opengl window
679     glFlush();
680     ReadInput(IsExit);
681   }
682  // infile.close();
683   //exit(0);
684 }
685 
686 
687 // Main
688 void main(int ac, char** av) {
689   initial();
690   
691   int winSizeX, winSizeY;
692   string name;
693   
694   if(ac == 3) {
695     winSizeX = atoi(av[1]);
696     winSizeY = atoi(av[2]);
697 //        cout<<"Done";
698   }
699   else { // default window size
700     winSizeX = 800;
701     winSizeY = 600;
702 
703   }
704   
705     
706 //  cout<<"Please input file name:"<<endl;
707 //  cin>>name;
708 //  infile.open(name.c_str());
709  // exit(0);
710  // infile.open("inp3.txt");
711 // infile.open(av[1]);
712   width  = winSizeX;
713   height = winSizeY;
714 
715   // initialize OpenGL utility toolkit (glut)
716   glutInit(&ac, av);
717 
718   // single disply and RGB color mapping
719   glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); // set display mode
720   glutInitWindowSize(winSizeX, winSizeY);      // set window size
721   glutInitWindowPosition(0, 0);                // set window position on screen
722   glutCreateWindow("Lab2 Window");       // set window title
723   
724   // set up the mouse and keyboard callback functions
725    // register the keyboard action function
726   glutKeyboardFunc(myKeyboard);
727   // displayFunc is called whenever there is a need to redisplay the window,
728   // e.g., when the window is exposed from under another window or when the window is de-iconified
729   glutDisplayFunc(displayFunc); // register the redraw function
730   
731   // set background color
732   glClearColor(0.0, 0.0, 0.0, 0.0);     // set the background to black
733   glClear(GL_COLOR_BUFFER_BIT); // clear the buffer
734 
735   // misc setup
736   glMatrixMode(GL_PROJECTION);  // setup coordinate system
737   glLoadIdentity();
738   gluOrtho2D(0, winSizeX, 0, winSizeY);
739   glShadeModel(GL_FLAT);
740   glFlush();
741   glutMainLoop();
742 }
743 
744 void DrawLines_4(int x1, int y1, int x2, int y2) //判断画哪一种线
745 {
746     if(x1 >= x2)
747     {
748         if(y1 >= y2)
749         {
750             swap(x1, x2);
751             swap(y1, y2);
752             if((y2-y1) >= (x2-x1))            
753                 drawLine2(x1, y1, x2, y2, 1);    
754             else
755                 drawLine1(x1, y1, x2, y2, 1);
756         }
757         else
758         {
759             if((y2-y1) >= (x1-x2))
760                 drawLine3(x1, y1, x2, y2, 1);
761             else
762                 drawLine4(x2, y2, x1, y1, 1);
763         }                
764     }
765     else
766     {
767         if(y2 >= y1)
768         {
769             if((y2-y1) <= (x2-x1))
770                 drawLine1(x1, y1, x2, y2, 1);
771             else
772                 drawLine2(x1, y1, x2, y2, 1);
773         }
774         else
775         {
776             if((y1-y2) <= (x2-x1))
777                 drawLine4(x1, y1, x2, y2, 1);
778             else
779                 drawLine3(x2, y2, x1, y1, 1);
780         }
781     }
782     
783     glFlush();
784 }
785 
786 // draw a dot at location with integer coordinates (x,y), and with color (r,g,b)
787 void drawDot(int x, int y, float r, float g, float b) 
788 {
789     glBegin(GL_POINTS);
790   
791     // set the color of dot
792     glColor3f(r, g, b);
793   
794     // invert height because the opengl origin is at top-left instead of bottom-left
795     glVertex2i(x , height - y);
796   
797     glEnd();
798 }
799 
800 // Draw line for dx>0 and dy>0
801 void drawLine1(int x1, int y1, int x2, int y2, bool xy_interchange) //0-45度
802 {
803     //cout << "Drawing Line1!" << endl;
804     int x = x1;
805     int y = y1;    
806 
807     int a = y2 - y1;
808     int b = x1 - x2;
809     int d = 2 * a + b;
810     int IncE = 2 * a;
811     int IncNE = 2 * (a + b);
812 
813     while(x <= x2)
814     {
815         if(d <= 0)
816         {
817             x++;
818             d += IncE;
819         }
820         else
821         {
822             x++;
823             y++;
824             d += IncNE;
825         }
826         
827         if(status == "square")
828             drawDot(x, height-y, 0.0, 10.0, 0.0);
829         //else if(judge_in(x, y))
830         else if(status == "triangle")
831             drawDot(x, height-y, 0.0, 0.0, 10.0);
832         else if(status == "view")
833             drawDot(x, height-y, 10.0, 0.0, 0.0);
834     }
835 }
836 
837 // Draw line for dx>0 and dy<0
838 void drawLine2(int x1, int y1, int x2, int y2, bool xy_interchange) //45-90度
839 {
840     //cout << "Drawing Line2!" << endl;
841     //转换为0-45度的情况
842     swap(x2, y2);
843     swap(x1, y1);
844 
845     int x = x1;
846     int y = y1;
847     
848     int a = y2 - y1;
849     int b = x1 - x2;
850     int d = 2 * a + b;
851     int IncE = 2 * a;
852     int IncNE = 2 * (a + b);
853 
854     while(x <= x2)
855     {
856         if(d <= 0)
857         {
858             x++;
859             d += IncE;
860         }
861         else
862         {
863             x++;
864             y++;
865             d += IncNE;
866         }
867         
868         if(status == "square")
869             drawDot(y, height-x, 0.0, 10.0, 0.0);
870         //else if(judge_in(y, x))
871         else if(status == "triangle")
872             drawDot(y, height-x, 0.0, 0.0, 10.0);
873         else if(status == "view")
874             drawDot(y, height-x, 10.0, 0.0, 0.0);
875     }    
876 }
877 
878 // Draw line for dx<0 and dy>0
879 void drawLine3(int x1, int y1, int x2, int y2, bool xy_interchange) //90-135度
880 {
881     //cout << "Drawing Line3!" << endl;
882     swap(x2, y2);
883     swap(x1, y1);
884     y1 = -y1;
885     y2 = -y2;
886     int x = x1;
887     int y = y1;
888 
889     int a = y2 - y1;
890     int b = x1 - x2;
891     int d = 2 * a + b;
892     int IncE = 2 * a;
893     int IncNE = 2 * (a + b);
894 
895     while(x <= x2)
896     {
897         if(d <= 0)
898         {
899             x++;
900             d += IncE;
901         }
902         else
903         {
904             x++;
905             y++;
906             d += IncNE;
907         }
908         
909         if(status == "square")
910             drawDot(-y, height-x, 0.0, 10.0, 0.0);
911         //else if(judge_in(-y, x))
912         else if(status == "triangle")
913             drawDot(-y, height-x, 0.0, 0.0, 10.0);
914         else if(status == "view")
915             drawDot(-y, height-x, 10.0, 0.0, 0.0);
916     }
917 }
918 
919 // Draw line for dx<0 and dy>0
920 void drawLine4(int x1, int y1, int x2, int y2, bool xy_interchange) //135-180度
921 {
922     //cout << "Drawing Line4!" << endl;
923     y1 = -y1;
924     y2 = -y2;
925     int x = x1;
926     int y = y1;
927     
928     int a = y2 - y1;
929     int b = x1 - x2;
930     int d = 2 * a + b;
931     int IncE = 2 * a;
932     int IncNE = 2 * (a + b);
933 
934     while(x <= x2)
935     {
936         if(d <= 0)
937         {
938             x++;
939             d += IncE;
940         }
941         else
942         {
943             x++;
944             y++;
945             d += IncNE;
946         }
947         
948         if(status == "square")
949             drawDot(x, height+y, 0.0, 10.0, 0.0);
950         //else if(judge_in(x, -y))
951         else if(status == "triangle")
952             drawDot(x, height+y, 0.0, 0.0, 10.0);
953         else if(status == "view")
954             drawDot(x, height+y, 10.0, 0.0, 0.0);
955     }
956 }

 

OpenGL多边形变换和裁剪

标签:

原文地址:http://www.cnblogs.com/dominjune/p/4523469.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!