图形学裁剪算法(一)Cohen-SutherLand裁剪算法(编码裁剪算法)

图形学裁剪算法(一)Cohen-SutherLand裁剪算法(编码裁剪算法)

算法原理

将线段分为以下三种情况处理
(1)若P1P2完全在窗口内,则显示该线段P1P2,–简取
(2)若P1P2完全在窗口外,则丢弃该线段。–简弃
(3)若线段不满足(1)(2)时,则把线段分为两段,其中一段完全在窗口外,再重复上述判断能否取或弃

编码

对于不同区域的点进行如下编码,假设窗口,左侧(XL)右侧(XR)上侧(YT)下侧(YB),
区域编码:对于点P(x,y) code=ABCD(二进制)
   x < XL D=1   x > XR   C=1
   y < YB B=1   y > YT    A=1
可获得该点对应得编码
如下图

在这里插入图片描述
对于之前得三种情况如下:
P1的编码 : code1       P2的编码 : code2
(1)完全在窗口内,则有 code1 | code2 = 0
(2)完全在窗口外,则有 code1 & code2 != 0
(3)与窗口相交,求交,将窗口外的线段丢弃,再进行裁剪

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);
}

源码

#include<iostream>
#include<easyx.h>
#include<graphics.h>
using namespace std;
#define LEFT 1
#define RIGHT 2
#define BOTTOM 4
#define TOP 8
#define XL 0
#define XR 200
#define YB 0
#define YT 100
int encode(float x,float y);
void Cohen_SutherLand(float x1,float y1,float x2,float y2);
void displayline(float x0,float y0,float x1,float y1,int color);
int main()
{
	Cohen_SutherLand(-10,-10,200,200);
	return 0;
}
int encode(float x,float y)
{
	int code=0;
	if(x<XL) code=code|LEFT;
	else if(x>XR) code=code|RIGHT;
	if(y<YB) code=code|BOTTOM;
	else if(y>YT) code=code|TOP;
	return code;
}
void Cohen_SutherLand(float x1,float y1,float x2,float y2)
{
	initgraph(640,480);
	setorigin(200,200);
	displayline(XL,YB,XR,YB,0xFFFFFF);
	displayline(XL,YT,XR,YT,0xFFFFFF);
	displayline(XL,YB,XL,YT,0xFFFFFF);
	displayline(XR,YB,XR,YT,0xFFFFFF);
	int code1,code2,code;
	float x,y;
	code1=encode(x1,y1);
	code2=encode(x2,y2);
	while(code1!=0||code2!=0)
	{
		if((code1&code2)!=0)
			return ;
		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;
			code1=encode(x,y);
		}
		else
		{
			x2=x;
			y2=y;
			code2=encode(x,y);
		}
	}
	displayline(x1,y1,x2,y2,0xFFFF00);
	getchar();
	getchar();
	closegraph();
}
void displayline(float x0,float y0,float x1,float y1,int color)
{
	int t;
	float dx,dy,k,y,x;
	dx=x1-x0;
	dy=y1-y0;
	k=dy/dx;
	if(k<=1)
	{
		y=y0;
		for(t=x0;t<=x1;t++)
		{
			putpixel(t,int(y+0.5),color);
			y=y+k;
		}
	}
	else
	{
		k=1/k;
		x=x0;
		for(t=y0;t<=y1;t++)
		{
			putpixel(int(x+0.5),t,color);
			x=x+k;
		}
	}
}

运行结果:
在这里插入图片描述

所用包链接

EasyX
链接:https://pan.baidu.com/s/1UQn2-iFlgbSbIfze_c0lSg
提取码:6j7r

  • 4
    点赞
  • 77
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值