编码实现Cohen-Sutherland端点编码算法(用矩形窗口裁剪一条直线段)

编码实现Cohen-Sutherland端点编码算法(用矩形窗口裁剪一条直线段)

#include<stdio.h>
#include<graphics.h>
struct PCB{
	float x0;
	float y0;
	float x1;
	float y1;
	float xl;
	float xr;
	float yl;
	float yu;
};


int k=0;

//进行0、1编码
int code(float x,float y,PCB *p){
	int d3,d2,d1,d0,temp;
	if(y>p[1].yu) d3=1;
	else d3=0;
	if(y<p[1].yl) d2=1;
	else d2=0;
	if(x>p[1].xr) d1=1;
	else d1=0;
	if(x<p[1].xl) d0=1;
	else d0=0; 
	temp=((d3*2+d2)*2+d1)*2+d0;
	return temp;
}
   
//求出直线端点与窗口坐标
float coordinate(PCB *p,float x,float y){
	if(y==0){
		y=p[1].y1-(p[1].y1-p[1].y0)*(p[1].x1-x)/(p[1].x1-p[1].x0);
		return y;
	}
	else if(x==0){
		x=p[1].x1-(p[1].y1-y)*(p[1].x1-p[1].x0)/(p[1].y1-p[1].y0);
		return x;
	}
}

//求出直线端点与窗口坐标
void change(int P1,int P2,PCB *p){
	float temp;
	int s1,s2,s3,s4;
	s1=P1&1;
	s2=P1&2;
	s3=P1&4;
	s4=P1&8;
	if(s1==1){
		temp=coordinate(p,p[1].xl,0);
		p[1].x0=p[1].xl;
		p[1].y0=temp;
	}
	else if(s2==2){
		temp=coordinate(p,p[1].xr,0);
		p[1].x0=p[1].xr;
		p[1].y0=temp;
	}
	else if(s3==4){
		temp=coordinate(p,0,p[1].yl);
		p[1].x0=temp;
		p[1].y0=p[1].yl;
	}
	else if(s4==8){
		temp=coordinate(p,0,p[1].yu);
		p[1].x0=temp;
		p[1].y0=p[1].yu;
	}
}

//确保P1在窗口外部
void Sutherland(int P1,int P2,PCB *p){
	int temp;
	float ss;
	if(P1==0){
		temp=P1;P1=P2;P2=temp;
		ss=p[1].x0;p[1].x0=p[1].x1;p[1].x1=ss;
		ss=p[1].y0;p[1].y0=p[1].y1;p[1].y1=ss;
	}
	change(P1,P2,p);
}

//CohenSutherland编码
void Cohen(PCB *p){
	int P1=code(p[1].x0,p[1].y0,p);
    int P2=code(p[1].x1,p[1].y1,p);
	//printf("%3d%3d\n",P1,P2);
	int s1,s2;
//printf("%5.1f%5.1f%5.1f%5.1f\n",p[1].x0,p[1].y0,p[1].x1,p[1].y1);
	s1=P1|P2;
	s2=P1&P2;
	if(s1==0){
		line((int)p[1].x0,(int)p[1].y0,(int)p[1].x1,(int)p[1].y1);
		k=1;
		//printf("%3f%3f%3f%3f",p[1].x0,p[1].y0,p[1].x1,p[1].y1);
	}
		//line((int)p[1].x0,(int)p[1].y0,(int)p[1].x1,(int)p[1].y1);
	else if(s2!=0){
		printf("舍弃该直线!");
		k=1;}
	else
		Sutherland(P1,P2,p);
}

//主函数,初始化
int main(){
	PCB p[1];
	int i,gmode,gd=DETECT;
	printf("输入直线端点坐标:\n");
	printf("起点:\n");
	scanf("%f%f",&p[1].x0,&p[1].y0);
	printf("终点:\n");
	scanf("%f%f",&p[1].x1,&p[1].y1);
	printf("输入窗口边界:\n");
	printf("xl=");
	scanf("%f",&p[1].xl);
	printf("xr=");
	scanf("%f",&p[1].xr);
	printf("yl=");
	scanf("%f",&p[1].yl);
	printf("yu=");
	scanf("%f",&p[1].yu);
	float q[10]={p[1].xl,p[1].yl,p[1].xl,p[1].yu,p[1].xr,p[1].yu,p[1].xr,p[1].yl,p[1].xl,p[1].yl}; //100,300,100,200
	int s[10];
	for(i=0;i<10;i++)
		s[i]=(int)q[i];
	initgraph(&gd,&gmode,"");
	drawpoly(5,s);
	//line((int)p[1].x0,(int)p[1].y0,(int)p[1].x1,(int)p[1].y1);//50,120,200,230
	for(i=0;i<4;i++)
		if(k!=1)
            Cohen(p);
    getchar();
	getchar();
    closegraph();
	return 0;
}

在这里插入图片描述
进行处理之前的图形:
在这里插入图片描述
进行处理后的图形:
在这里插入图片描述

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值