计算机图形学中的边线段裁剪算法c++程序实现
这个代码是同学写的,自己只是拿来应付老师的,各位小伙伴也可以这样
#include <graphics.h>
#include <conio.h>
//定义宏变量
#define LEFT 1
#define RIGHT 2
#define BOTTOM 4
#define TOP 8
//int XL=300, XR=700, YB=700, YT=300;
int XL=100, XR=500, YB=500, YT=100;
int encode(int x,int y)
{
int c=0;
if(x<XL) c=c|LEFT;
else if(x>XR) c=c|RIGHT;
if(y>YB) c=c|BOTTOM;
else if(y<YT) c=c|TOP;
return c;
}
// 使用中点算法画任意斜率的直线(包括起始点,不包括终止点)
void MidpointLine(int x1,int y1,int x2,int y2,COLORREF color) //中点画线法
{
int x = x1, y = y1; //初始化x,y
int a = y1 - y2, b = x2 - x1; //a,b分别为x和y的增量
//考虑四种情况,分别计算增量
int deltx = (b >= 0 ? 1 : (b = -b, -1));
int delty = (a <= 0 ? 1 : (a = -a, -1));
putpixel(x, y, color);
int d, delt1, delt2;
if (-a <= b) // 斜率绝对值 <= 1
{
d = 2 * a + b;
delt1 = 2 * a;
delt2 = 2 * (a + b);
while(x != x2)
{
if (d < 0)
y += delty, d += delt2;
else
d += delt1;
x += deltx;
putpixel(x, y, color);
}
}
else // 斜率绝对值 > 1
{
d = 2 * b + a;
delt1 = 2 * b;
delt2 = 2 * (a + b);
while(y != y2)
{
if(d < 0)
d += delt1;
else
x += deltx, d += delt2;
y += delty;
putpixel(x, y, color);
}
}
}
//画裁剪区域
void DrawArea(int x1,int y1,int x2,int y2,int color){
MidpointLine(x1-50,y1,x2+50,y1,color);
MidpointLine(x2,y1-50,x2,y2+50,color);
MidpointLine(x2+50,y2,x1-50,y2,color);
MidpointLine(x1,y2+50,x1,y1-50,color);
}
//直线裁剪算法
void C_S_Line_CLip(int x1,int y1,int x2,int y2,int XL,int XR,int YB,int YT)
{
//code1 和 code2是每个断点对应编码
int code1,code2,code;
int x,y;
//初始化端点编码
code1=encode(x1,y1);
code2=encode(x2,y2);
while(code1!=0||code2!=0)
{
//相交不为0,第二种情况,全舍去
if((code1&code2)!=0) return;
code=code1;
if(code==0) code=code2;
if((LEFT&code)!=0)//线段与左边界相交
{
x=XL;
y=y1+(y2-y1)*(XL-x1)/(x2-x1);
}
else if((RIGHT&code)!=0)//线段与右边界相交
{
x=XR;
y=y1+(y2-y1)*(XR-x1)/(x2-x1);
}
else if((BOTTOM&code)!=0)//线段与下边界相交
{
y=YB;
x=x1+(x2-x1)*(YB-y1)/(y2-y1);
}
else if((TOP&code)!=0)//线段与上边界相交
{
y=YT;
x=x1+(x2-x1)*(YT-y1)/(y2-y1);
}
if(code==code1){
x1=x;
y1=y;
code1=encode(x,y);
}
else{
x2=x;
y2=y;
code2=encode(x,y);
}
}
MidpointLine(x1,y1,x2,y2,RED);
return;
}
int main()
{
initgraph(800,800);
//画裁剪区域
DrawArea(XL,YT,XR,YB,255);
//裁剪直线
C_S_Line_CLip(200,100,100,50,XL,XR,YB,YT);//区域外
C_S_Line_CLip(200,600,600,200,XL,XR,YB,YT);//部分区域内
C_S_Line_CLip(400,400,600,600,XL,XR,YB,YT);//区域内
// 按任意键退出
getch();
return 0;
}