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 }
时间: 2024-10-11 18:15:41