裁剪算法(计算机图形学)

#include <graphics.h>
#include <conio.h>
#define LEFT 1
#define RIGHT 2
#define BOTTOM 4
#define TOP 8
int XL=150, XR=350, YB=350, YT=150;
//编码算法
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 DisplayLine(int x1, int y1, int x2, int y2, int color)
{
	int x = x1, y = y1;
	int a = y1 - y2, b = x2 - x1;
	int cx = (b >= 0 ? 1 : (b = -b, -1));
	int cy = (a <= 0 ? 1 : (a = -a, -1));

	putpixel(x, y, color);

	int d, d1, d2;
	if (-a <= b)		// 斜率绝对值 <= 1
	{
		d = 2 * a + b;
		d1 = 2 * a;
		d2 = 2 * (a + b);
		while(x != x2)
		{
			if (d < 0)
				y += cy, d += d2;
			else
				d += d1;
			x += cx;
			putpixel(x, y, color);
		}
	}
	else				// 斜率绝对值 > 1
	{
		d = 2 * b + a; 
		d1 = 2 * b;
		d2 = 2 * (a + b);
		while(y != y2) 
		{ 
			if(d < 0)
				d += d1; 
			else 
				x += cx, d += d2; 
			y += cy; 
			putpixel(x, y, color);
		} 
	}
}

//画裁剪区域:Breasenham方法和中点画线法均不能画出该裁剪区域
void DisplayRec(int x1,int y1,int x2,int y2,int color){
    DisplayLine(x1-50,y1,x2+50,y1,color);
	DisplayLine(x2,y1-50,x2,y2+50,color);
	DisplayLine(x2+50,y2,x1-50,y2,color);
	DisplayLine(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)
{
   int code1,code2,code;
   int x,y;
   code1=encode(x1,y1);
   code2=encode(x2,y2);
   while(code1!=0||code2!=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);
	   }
   }
   DisplayLine(x1,y1,x2,y2,RED);
   return;
}


int main()
{
	int gdriver=DETECT, gmode;
	initgraph(&gdriver,&gmode,"");//根据测试结果初始化图形界面

	//int points[]={150,150,350,150,350,350,150,350,150,150};//定义多边形点的坐标
	// drawpoly(5,points);          //画多边形

	//画裁剪区域
	DisplayRec(150,150,350,350,GREEN);


	//裁剪直线
	DisplayLine(200,100,300,145,BLUE);
	C_S_Line_CLip(200,100,300,145,150,350,350,150);//全部区域外

        C_S_Line_CLip(200,200,250,250,150,350,350,150);//区域内

        DisplayLine(50,180,400,180,YELLOW);
	C_S_Line_CLip(50,180,400,180,150,350,350,150);//部分区域内

    // 按任意键退出
	getch();
	closegraph();

	return 0;
}

  • 1
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值