java实现裁剪算法代码_Cyrus-Beck图像裁剪算法归纳

此算法能使用任意多边形对一条直线段进行裁剪。

类GLdoublePoint: 公有—GLdouble x ,y;

类line:                 公有—GLdoublePoint first,second;

linelist:                 line型数据组成的链表,用于描述多边形;

伪代码:

int  CyrusBeck(line&  seg , linelist&  l)

{

double  numer , denom ;

double  tIn = 0.0 , tOut = 1.0;

Vector  c , temp;

c = seg.second - seg.first;

for(int  i = 0 ; i < l.num ; i++)

{

temp = l.line[i].pt - first ;  // pt为此时多边形某边上的任意一点

numer = dot(l.line[i].norn , temp);

denom = dot(l.line[i].norn , c);  // dot()函数为求两向量的点积,自行编写

if(!chopCI(numer , denom , tIn , tOut))  return  0 ; // chopCI()是用来计算射线与多边型每条边相交 的时间,并判断射线在交点处是射入还是射出,伪代码在后面

}

if(tOUt < 1.0)                                                                   //进行裁剪

{

seg.second.x = seg.first.x + c.x * tOut ;

seg.second.y = seg.first.y + c.y * tOut ;

}

if(tIn > 0.0)

{

seg.first.x = seg.first.x + c.x * tIn ;

seg.first.y = seg.first.y + c.y * tIn ;

}

return 1;

}

int  chopCI(double  numer , double  denom ,double  tIn ,double  tOut)

{

double  tHit;

if(denom < 0)                                                              //射线射入

{

tHit = numer / denom ;

if (tHit > tOut) return 0;

else  if(tHit > tIn)   tIn = tHit ;

}

else if(denom > 0)                                                       // 射线射出

{

tHit = numer / denom ;

if(tHit < hIn) return 0;

else  if(tHIt > tIn) tOut = tHIt ;

}

else                                                                            //射线与边平行

if(numer <= 0 )  return 0;

return 1;

}

说明:

设某射线起始点为A,单位向量为c;某直线l,其上任意一点B,法向量n;先判断A和B的关系。

假设A与B相交,则焦点A+t*c与B形成的向量与n垂直,则有:

n ●(A+c*t — B)= 0 (1)

此处可以将参数t看为是时间,则t为射线击中l的时间,记为tHit。

(1)式经变换可得:tHit = n ●(B—A)/ (n ● c)

由向量点积的性质可得:若n ● c>0 ,则射线沿法线方向

若n ● c<0 ,则射线与法线相反

若n ● c=0 ,则法线与射线平行

代码中的tIn和tOut可以理解为候选区间,也就是射线现存的部分,剪裁时就是根据射线是射入还是射出以及tHIt和tIn与tOut的关系来修改tOut和tIn,避免了频繁进行改变点的运算,因为计算机图形学中点与向量的定义很相似,容易出错。

Cyrus-Beck裁剪算法就是依据以上方法用多边形的每条边对seg进行判断,并把剪裁后的线段返回到seg中,思路简单但是运算量较大,也不实用来计算边数多的多边形,同时此算法也只适用于凸多边形。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值