同构坐标系下的OpenGL sutherland-hodgman多边形裁剪算法(4D,CCS)

时间:2017-02-06 05:26:44

标签: opengl graphics directx perspective clipping

我有两个问题。 (我在下面标记为1,2)

在OpenGl中,剪辑由sutherland-hodgman完成。 但是,我想知道如何在均匀系统(4D)中使用sutherland-hodgman算法

我做了一个情况。 在VCS中,有一条线,R =(0,3,-2,1),S =(0,0,1,1)(线的终点) 平截头体是对的= 1,左= -1,近= 1,远= 3,顶部= 4,底部= -4 因此,投影矩阵P是

1    0    0   0
0   1/4   0   0
0    0   -2  -3
0    0   -1   0 

如果我们用P计算线,那么每个端点都是那样的

R' = (0, 3/4, 1, 2), S' = (0, 0, -5, -1)

我知道现在不应该进行透视划分,因为如果我们进行透视划分,裁剪结果就不正确了。

  1. 我很好奇。是什么造成了正确的裁剪,因为我们不仅仅进行了视角分割。这里有什么数学属性?

  2. 如何在上述情况下计算剪辑结果?

  3. (在w-y坐标系中出现两个交点的事实让我感到困惑。我认为结果线是一个,而不是分成两部分)

2 个答案:

答案 0 :(得分:2)

我不太确定你是否正确地理解了sutherland-hodgman算法(或者至少我没有得到你的例子)。因此,我将在这里证明,在视角分割之前或之后是否发生剪切并没有任何区别。证据仅针对一个平面显示(必须对所有6个平面进行裁剪),因为在此之后应用多个此类裁剪操作在此处没有区别。

假设我们在剪辑空间中有两个点(如你所描述的)R'和S'。我们有一个剪切平面P,用粗糙的法线形式[n,p]给出(如果我们采用左平面,这是[1,0,0,1])。

如果我们要在纯三维空间(R ^ 3)中计算,那么检查一条线是否穿过这个平面将通过计算两个点到平面的有符号距离并检查符号是否不同来完成。点X = [x / w,y / w,z / w]的符号距离由

给出
D = dot(n, X) + p

让我们写下我们的实际等式(包括透视划分):

d = n_x * x/w + n_y * y/w + n_z * z/w + p

为了找到确切的交点,我们再次在R ^ 3空间中计算两个点(A = R'/ R'w,B = S'/ S'w)到平面的距离(da,db)并执行线性插值(我只会在这里写出x坐标的方程式,因为y和z的工作方式类似):

x = A_x * (1 - da/(da - db)) + A_y * (da/(da-db))
x = R'x/R'w * (1 - da/(da - db)) + S'x/S'w * (da/(da-db))

并且w = 1(因为我们在两个点之间进行插值,其中w = 1)

现在我们已经从the previous discussion得知,剪切必须在透视分割之前发生,因此我们必须调整这个等式。这意味着,对于每个点,剪切立方体具有不同的缩放比例w。我们看到当我们尝试在P ^ 3中执行相同的操作时(在透视分割之前)会发生什么:

首先,我们“恢复”视角除以得到X = [x,y,z,w],其中到平面的距离由

给出
d = n_x * x/w + n_y * y/w + n_z * z/w + p
d = (n_x * x + n_y * y + n_z * z) / w + p
d * w = n_x * x + n_y * y + n_z * z + p * w
d * w = dot([n, p], [x,y,z,w])
d * w = dot(P, X)

由于我们只对整个计算的符号感兴趣,我们的操作没有改变它们,我们可以比较D*w s并得到与R ^ 3相同的由内而外的结果。

对于两个点R'和S',计算出的P ^ 3中的距离是dr = da * R'w和ds = db * S'w。当我们现在使用与上面相同的插值方程但是对于R'和S',我们得到x:

x' = R'x * (1 - (da * R'w)/(da * R'w - db * S'w)) + S'x * (da * R'w)/(da * R'w - db * S'w)

在第一个视图中,这看起来与我们在R ^ 3中得到的结果有很大不同,但由于我们仍然在P ^ 3(因此是x'),我们仍然需要对结果进行透视除法(这是这里允许,因为插值点总是在视锥体的边界处,因此除以w将不会引入任何问题)。内插的w分量如下:

w' = R'w * (1 - (da * R'w)/(da * R'w - db * S'w)) + S'w * (da * R'w)/(da * R'w - db * S'w)

当计算x / w时我们得到

x = x' / w';
x = R'x/R'w * (1 - da/(da - db)) + S'x/S'w * (da/(da-db))

与计算R ^ 3中的所有内容完全相同。

结论:插值给出相同的结果,无论我们先执行透视分割然后插值还是先插补然后再划分。但是对于第二种变体,我们避免了点从观察者后面翻到前面的问题,因为我们只是将点保证在视锥体的内部(或边界)上。

答案 1 :(得分:0)

你说的是同系统(4D)中的多边形裁剪,但是根据你的问题我假设你实际上是指齐次坐标,这更有意义。 (有许多可能的同源系统。)

好的,所以你想使用“4D”坐标,这实际上是“3D坐标和w术语”。 w项代表(投影变换)投影项,其部分地将屏幕空间坐标与原始世界空间位置相关联。假设您对投影空间剪辑不感兴趣,则该术语无关紧要。

我假设这是因为你描述的剪辑框在3D平面上是轴对齐的。即使它在3D空间中旋转或缩放,每个平面仍然是3D平面,第4个坐标始终为“1”。

所以如何剪辑:

剪切线段L对着剪切框的每个平面,即总共6个剪切平面(您恰当地描述每个剪裁平面的法线),并查看该线是否共享任何交叉点v平面P这样

  • v位于线段上(即 t 介于0和1之间)
  • v位于平面P的范围内(即坐标不应位于任何相邻平面之外。由于您使用的是轴对齐的剪裁平面,因此很容易检查。)

(3D + w)线与其中一个3D平面之间的任何这些交叉都发生在3D中,并且交叉点必须是3D坐标。您可以使用第4个坐标将每个坐标扩展为“4D”坐标,以便您可以使用4x4矩阵进一步转换它们以进行视图和投影处理。