📄 4-2.c
字号:
/*多边形裁剪*/
/*坐标系:屏幕左上角为原点,向下为纵坐标正方向*/
#include<graphics.h>/*加入c图形库*/
#include<conio.h>/*键盘控制*/
#include<math.h>
#define LEFT 1
#define RIGHT 2
#define BOTTOM 4
#define TOP 8
#define XL 100
#define XR 500
#define YB 100
#define YH 300/*定义视窗四边*/
encode(x,y,code)/*编码算法*/
int x,y;
int *code;
{int c;
c=0;
if(x<XL)c=c|LEFT;
else if(x>XR)c=c|RIGHT;
if(y<YB)c=c|BOTTOM;
else if(y>YH)c=c|TOP;
*code=c;
return;
}
draw_ett(x1,y1,x2,y2,x,y)/*求最远可见点*/
int x1,x2,y1,y2;
int *x,*y;
{
int code1,code2,code;
float xx,yy;
float d,d1,d2;/*设成float型是为了防止平方时溢出*/
encode(x1,y1,&code1);
encode(x2,y2,&code2);
if(code2==0)/*(x2,y2)端点可见即为(x1,y1)的最远可见点*/
{
xx=x2;yy=y2;
*x=xx;
*y=yy;
return;
}
if((code1&code2)!=0)return;/*原线段不可见*/
L1: xx=(x1+x2)/2;
yy=(y1+y2)/2;
encode((int)xx,(int)yy,&code);/*不将xx、yy变成整型将产生错误*/
d1=(yy-y1)*(yy-y1);
d2=(xx-x2)*(xx-x2);/*这里求中点距顶点位置,请思考没用一个顶点坐标的原因(注意d是float型)*/
d=sqrt(d1+d2);
// printf("%d,%d,%f,%f,%f,%f,%f\n",x1,y1,xx,yy,d1,d2,d);
if(getch()==17)exit();/*读入键盘按键*/
if(d<=1){
*x=xx;
*y=yy;
return;
}
if((code&code2)!=0)/*中点到(x2,y2)端点线段不可见*/
{
x2=xx;
y2=yy;
}
else {
x1=xx;
y1=yy;
}
putpixel(xx,yy,14);/*画出中点位置便于观察*/
goto L1;
}
void main()
{
int x1,y1,x2,y2,xx,yy,xxx,yyy;
int driver,mode;
driver=DETECT;/*初始化显示模式参数*/
initgraph(&driver,&mode,"..\\bgi");/*初始化显示为VGA驱动的640*480、16色模式*/
printf("Press any key to continue except 'Ctrl+Q' to quit.\n");
//scanf("%d,%d,%d,%d",&x1,&y1,&x2,&y2);/*可以手动输入直线两顶点*/
x1=100;y1=80;x2=500;y2=350;/*直线两顶点*/
setcolor(12);
line(x1,y1,x2,y2);
line(XL,YH,XR,YH);
line(XL,YB,XR,YB);
line(XL,YH,XL,YB);
line(XR,YH,XR,YB);/*视窗边框*/
xx=0;
yy=0;
xxx=0;
yyy=0;
draw_ett(x1,y1,x2,y2,&xx,&yy);/*求得(x1,y1)的最远端可见点*/
draw_ett(xx,yy,x1,y1,&xxx,&yyy);/*求得(xx,yy)的最远端可见点*/
line(x1,y1,x2,y2);/*覆盖运行过程中在原直线上产生的中点*/
setcolor(14);
line(xx,yy,xxx,yyy);/*剪切后直线*/
if(getch()==17)exit();/*读入键盘按键*/
closegraph();/*关闭图形模式*/
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -