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 }