1 /************************************************************* 2 裁剪窗口 3 4 *************************************************************/ 5 6 7 #include <GL/glut.h> 8 #include<cstdio> 9 #include<cmath> 10 11 #define ymin -300 12 #define ymax 300 13 #define xmin -400 14 #define xmax 400 15 16 struct point 17 { 18 int x; 19 int y; 20 }; 21 22 typedef enum 23 { 24 L,R,B,T 25 }BD; 26 27 point s,e; 28 point in[100],out[100]; 29 int len=0; 30 31 32 void init() 33 { 34 glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE); //什么单缓存的东西,现在不懂什么意思,就当通用条件 35 glutInitWindowPosition(0, 0); //图片出现的位置 36 glutInitWindowSize(400, 300); //图片的长和宽 37 glutCreateWindow("pb-图形学题1"); //图片的名字 38 39 glClearColor(0.0, 0.0, 0.0, 0.0); 40 glMatrixMode(GL_PROJECTION); 41 gluOrtho2D(-1000, 1000, -1000, 1000); 42 43 glRectf(-0.5f, -0.5f, 0.5f, 0.5f); 44 glClear(GL_COLOR_BUFFER_BIT); 45 glColor3f(1.0, 0.0, 0.0); 46 47 printf("请输入裁剪直线的起点和终点: "); 48 scanf("%d%d%d%d",&s.x,&s.y,&e.x,&e.y); 49 if (s.x>e.x) 50 { 51 point temp; 52 temp=s; 53 s=e; 54 e=temp; 55 } 56 printf("请输入多边形的端点"); 57 while (~scanf("%d%d",&in[len].x,&in[len++].y)); 58 len--; 59 in[len]=in[0]; 60 61 } 62 63 64 void setPixel (GLint x,GLint y,GLint nx,GLint ny) //描点函数,表示从x,y到nx,ny的矩形全部涂色 65 { 66 glBegin(GL_LINES); 67 glVertex2i(x, y); 68 glVertex2i(nx,ny); 69 glEnd(); 70 } 71 72 bool insert(point s,BD b) //判断短知否在边界内 73 { 74 switch(b) 75 { 76 case L: 77 if (s.x<=xmin) return false; 78 break; 79 case R: 80 if (s.x>=xmax) return false; 81 break; 82 case B: 83 if (s.y<=ymin) return false; 84 break; 85 case T: 86 if (s.y>=ymax) return false; 87 break; 88 } 89 return true; 90 } 91 92 point check(point s,point e,BD b) // 计算直线与边界的交点 93 { 94 point pi; 95 int k; 96 switch(b) 97 { 98 case L: 99 pi.x=xmin; 100 if (s.x!=e.x) pi.y=s.y+(xmin-s.x)*(e.y-s.y)/(e.x-s.x); 101 else pi.y=s.y; 102 break; 103 case R: 104 pi.x=xmax; 105 if (s.x!=e.x) pi.y=s.y-(s.x-xmax)*(e.y-s.y)/(e.x-s.x); 106 else pi.y=s.y; 107 break; 108 case B: 109 pi.y=ymin; 110 if (e.y!=s.y) pi.x=s.x+(e.x-s.x)*(ymin-s.y)/(e.y-s.y); 111 else pi.x=s.x; 112 break; 113 case T: 114 pi.y=ymax; 115 if (e.y!=s.y) pi.x=s.x-(e.x-s.x)*(s.y-ymax)/(e.y-s.y); 116 else pi.x=s.x; 117 break; 118 } 119 return pi; 120 } 121 122 int EC(BD b) //多边形裁剪 123 { 124 int pl=0; 125 point s=in[0]; 126 for (int i=1;i<=len;i++) 127 { 128 if (!insert(s,b)&&insert(in[i],b)) 129 { 130 out[pl++]=check(s,in[i],b); 131 out[pl++]=in[i]; 132 } 133 if (insert(s,b)&&insert(in[i],b)) 134 { 135 out[pl++]=in[i]; 136 } 137 if (insert(s,b)&&!insert(in[i],b)) 138 { 139 out[pl++]=check(in[i],s,b); 140 } 141 s=in[i]; 142 } 143 return pl; 144 } 145 146 147 bool LinTai(point &s,point &e) //线裁剪 148 { 149 150 //上裁剪 151 if (s.y>=ymax&&e.y>=ymax) return false; 152 if (s.y>=ymax) 153 { 154 s.x+=(s.y-ymax)*(e.x-s.x)/(s.y-e.y); 155 s.y=ymax; 156 } 157 if (e.y>=ymax) 158 { 159 e.x-=(e.y-ymax)*(e.x-s.x)/(e.y-s.y); 160 e.y=ymax; 161 } 162 163 //下裁剪 164 if (s.y<=ymin&&e.y<=ymin) return false; 165 if (s.y<=ymin) 166 { 167 s.x+=(ymin-s.y)*(e.x-s.x)/(e.y-s.y); 168 s.y=ymin; 169 } 170 if (e.y<=ymin) 171 { 172 e.x-=(ymin-e.y)*(e.x-s.x)/(s.y-e.y); 173 e.y=ymin; 174 } 175 176 //右裁剪 177 if (s.x>=xmax&&e.x>=xmax) return false; 178 if (e.x>=xmax) 179 { 180 e.y-=(e.x-xmax)*(e.y-s.y)/(e.x-s.x); 181 e.x=xmax; 182 } 183 184 //左裁剪 185 if (s.x<=xmin&&e.x<=xmin) return false; 186 if (s.x<=xmin) 187 { 188 s.y+=(xmin-s.x)*(e.y-s.y)/(e.x-s.x); 189 s.x=xmin; 190 } 191 192 return true; 193 } 194 195 void myDisplay() 196 { 197 glBegin(GL_POLYGON); 198 glVertex2f(xmin,ymax); 199 glVertex2f(xmax,ymax); 200 glVertex2f(xmax,ymin); 201 glVertex2f(xmin,ymin); 202 glEnd(); 203 glFlush(); 204 205 point s1=s,e1=e; 206 if (LinTai(s,e)) 207 { 208 209 210 printf("%d %d %d %d ",s1.x,s1.y,s.x,s.y); 211 212 glColor3f(0.0, 0.0, 1.0); 213 setPixel(s.x,s.y,s1.x,s1.y); 214 setPixel(e.x,e.y,e1.x,e1.y); 215 216 glColor3f(0.0, 1.0, 0.0); 217 setPixel(s.x,s.y,e.x,e.y); 218 } 219 else 220 { 221 glColor3f(0.0, 0.0, 1.0); 222 setPixel(s1.x,s1.y,e1.x,e1.y); 223 } 224 225 glFlush(); 226 227 int i,j; 228 glColor3f(1.0, 0.0, 1.0); 229 glBegin(GL_LINE_LOOP); 230 for (i=0;i<len;i++) 231 glVertex2f(in[i].x,in[i].y); 232 glEnd(); 233 glFlush(); 234 for (i=0;i<4;i++) 235 { 236 237 len=EC(BD(i)); 238 for(j=0;j<len;j++) in[j]=out[j]; 239 in[len]=out[0]; 240 241 } 242 glColor3f(1.0, 1.0, 0.0); 243 glBegin(GL_LINE_LOOP); 244 for (i=0;i<len;i++) 245 glVertex2f(in[i].x,in[i].y); 246 glEnd(); 247 248 glFlush(); 249 } 250 251 int main(int argc, char *argv[]) 252 { 253 glutInit(&argc, argv); 254 init(); //初始化数据 255 glutDisplayFunc(&myDisplay); //调用函数 256 glutMainLoop(); //开始程序 257 return 0; 258 }