直线段裁剪算法一:Cohen-Sutherland算法
//编译环境:Visual C++ 6.0,EasyX_20190219(beta)
#include
#include
#include
#define left 1
#define right 2
#define bottom 4
#define top 8
using namespace std;
//设置裁剪框的大小和位置
double xl=120,xr=320,yt=240,yb=150;
//编码
void encode(double x,double y,int &code)
{
int c=0;
if(xxr) {c=c+right;}
if(yyt) {c=c+top;}
code=c;
}
//Cohen-Sutherland裁剪算法
int CS_LineClip(double x1,double y1,double x2,double y2)
{
int code1,code2,code;
int x,y;
encode(x1,y1,code1);
encode(x2,y2,code2);
while(code1!=0||code2!=0)//都在里面时,直接画线,否则进行判断
{
if((code1&code2)!=0) return 0;//都在外面舍弃
code=code1;
if(code1==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;encode(x,y,code1);}
else
{x2=x;y2=y;encode(x,y,code2);}
}
line(x1,y1,x2,y2);
return 0;
}
int main()
{
double x1,y1,x2,y2;
initgraph(640, 480);
POINT points[]={ {xl,yt}, {xr,yt}, {xr,yb}, {xl,yb}};
polygon(points,4);
//用鼠标来获取两个点的坐标
MOUSEMSG m; // 定义结构体保存鼠标消息
while (true)
{flag:
m = GetMouseMsg();// 获取一次鼠标消息
switch (m.uMsg)//判断鼠标信息类型
{
case WM_LBUTTONDOWN:
x1 = m.x; y1 = m.y; //鼠标第一次按下时,获取鼠标当前坐标
while (true)
{
m = GetMouseMsg();// 再次获取一条鼠标消息
switch (m.uMsg)
{
case WM_LBUTTONDOWN:
x2 = m.x; y2 = m.y;//鼠标第二次按下时,得到坐标
setcolor(RED);
line(x1, y1, x2, y2);
setcolor(YELLOW);
CS_LineClip(x1, y1, x2, y2);
goto flag;
}
}
}
}
_getch();
closegraph();
return 0;
}
演示如下所示:
直线段裁剪算法二:梁友栋-Barsky线段裁剪算法
//编译环境:Visual C++ 6.0,EasyX_20190219(beta)
#include
#include
#include
using namespace std;
//设置裁剪框的大小和位置,全局变量
double xl=120,xr=250,yt=270,yb=160;
bool ClipT(double q,double d,double &t0,double &t1)
{//当线段完全不可见时,返回false,否则,返回true
double r;
if(q<0)
{
r=(double)d/(double)q;
if(r>t1)
return false;
else if(r>t0)
{t0=r;return true;}
}
else if(q>0)
{
r=(double)d/(double)q;
if(r