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("请输入裁剪直线的起点和终点:\n");
 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\n",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  }

 

posted on 2016-06-10 13:58  pb2016  阅读(876)  评论(0编辑  收藏  举报