Cohen-Sutherland直线段的裁剪算法

该算法又称编码算法,裁剪窗口的四条边所在的直线可以把平面分为9个区域,对各个区域的编码包括四位也就是内0外1(比如x坐标小于left记为1,其它记为0),裁剪窗口所在的区域为0000,对于直线段上的端点进行编码,等于该端点所在的区域的编码。编码后就容易判断两个端点的情况,比如求与不等于0,该线段在裁剪窗口之外。

具体算法代码如下:


typedef struct {
 unsigned int all;
 unsigned left, top, right, bottom;
} OutCode;
void CompOutCode(float x, float y, RECT *rect, OutCode *outCode)
{
 outCode->all = 0;
 outCode->left = outCode->top = outCode->right = outCode->bottom = 0;
 if (x < rect->left)
 {
  outCode->left = 1;
  outCode->all += 1;
 }
 if (y < rect->top)
 {
  outCode->top = 1;
  outCode->all += 2;
 }
 if (x > rect->right)
 {
  outCode->right = 1;
  outCode->all += 4;
 }
 if (y > rect->bottom)
 {
  outCode->bottom = 1;
  outCode->all += 8;
 }
}
void CohenSutherlandLineClip(HDC hdc, float x0, float y0, float x1, float y1, RECT *rect)
{
 bool accept, done;
 OutCode outCode0, outCode1;
 
 float x, y;
 accept = false;
 done = false;
 CompOutCode(x0, y0, rect, &outCode0);
 CompOutCode(x1, y1, rect, &outCode1);
 do {
  if (outCode0.all == 0 && outCode1.all == 0)
  {
   accept = true;
   done = true;
  }
  else if ((outCode0.all & outCode1.all) != 0)
  {
   done = true;
  }
  else
  {
   OutCode *outCodeOut;
   if (outCode0.all != 0)
    outCodeOut = &outCode0;
   else
    outCodeOut = &outCode1;

   if (outCodeOut->left)
   {
    x = rect->left;
    y = y0+(y1-y0)*(rect->left-x0)/(x1-x0);
   }
   else if (outCodeOut->top)
   {
    x = x0+(x1-x0)*(rect->top-y0)/(y1-y0);
    y = rect->top;
   }
   else if (outCodeOut->right)
   {
    x = rect->right;
    y = y0+(y1-y0)*(rect->right-x0)/(x1-x0);
   }
   else if (outCodeOut->bottom)
   {
    x = x0+(x1-x0)*(rect->bottom-y0)/(y1-y0);
    y = rect->bottom;
   }

   if (outCodeOut == &outCode0)
   {
    x0 = x;
    y0 = y;
    CompOutCode(x0, y0, rect, &outCode0);
   }
   else
   {
    x1 = x;
    y1 = y;
    CompOutCode(x1, y1, rect, &outCode1);
   }
  }
 } while (!done);

 if (accept)
 {
  MoveToEx(hdc, (int)(x0+0.5f), (int)(y0+0.5f), NULL);
  LineTo(hdc, (int)(x1+0.5f), (int)(y1+0.5f));
 }
}


该代码基于《计算机图形学》书里的代码修改而成,原书中的代码存在一些问题。

完整的代码可以从这里下载:http://download.csdn.net/detail/qiuchangyong/9763109




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值