从零实现3D图像引擎:(3)超级重要的2D矩形裁剪

1. 数学分析

为什么我们要画2D直线,要做2D的直线-矩形裁剪?原因很简单,无论游戏世界是2D的还是3D的,最终都要投影到玩家的屏幕上,3D的东西最终要是要投影到视平面上。所以3D游戏仍然有很多东西要在2D视平面上做。对于3D游戏的裁剪就有两种方法:一是在3D空间做裁剪,利用视域体的各个面与三角形中直线的关系来做,这叫做立方体空间裁剪;另一种是,把3D物体先投影在2D视平面上,然后在视平面上对2D直线做矩形裁剪,叫作图像空间裁剪。三角形都是由直线组成的,屏幕是矩形的,所以用矩形裁剪一条直线是非常重要的,而且也不是想当然的简单的,也有很多因素要考虑。

 

1) 直线被矩形裁剪的四种情况

直线被矩形裁剪只有以下4种情况,如图:

裁剪情况

 

2) 裁剪的核心问题?

我们来看看,裁剪的核心问题是什么:

裁剪的核心问题

如上图,两个端点分别为p0,p1的直线线段,被某一矩形裁剪。裁剪的过程是给定输入值x0,y0,x1,y1和矩形RECT,输出被裁剪后的直线两端点p0',p1'的坐标x0',y0',x1',y1'。

 

通过观察上图,我们可以知道,我们其实就在求两条直线的交点,一条是红线,一条是矩形的某个边。这让我们想起了几何学时的几种直线表示形式,然后求交点就是解一个方程组的过程。这没有错,但是我们可以走捷径,因为矩形的某个边不是水平线,就是垂直线,所以这第二条直线的表示非常简单。垂直线是x = c,水平线是y = c。

 

我们来表示一下这条红线。比如我们用点斜式:

斜率m = (y2 - y1) / (x2 - x1)

点斜式: y - y1 = m * (x - x1)

 

整理后,用y表示x:

x = (y - y1) / m + x1

也可以用x表示y:

y = m * (x - x1) + y1

 

所以与某个矩形的边的交点,可以把那个边线的表示形式直接代入,即可求得。

 

3) Cohen-Sutherland

上面我们解决了核心问题,那就是如何求交点。而Cohen-Sutherland算法为我们解决了另一个文章开头所说的问题,就是如何处理直线与矩形之间的4种关系。

 

该算法虽然简单,但极其精妙,后面会讲如何精妙!它把空间分成了各个部分,并赋予了相应的位代码,所以只使用少量的if语句,并且还是位运算,根据直线的两端点,即可判断出是上面哪种关系,如图:

Cohen-Sutherland

如果你想感动一下,那一定要非常仔细的研究这个图了。

首先,我们看红色代码的部分,请不要看那个黑色的十进制code,中间裁剪矩形的代码是0000。正左方、正右方、正下方、正上方分别是:

0001

0010

0100

1000

即,他们每个是其中的一个位标记,所以可以通过两两做或操作(|),来得到斜着的4个角的代码(绿色)。

首先,根据这些特性,我们可以做一些工作了&

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值