半圆柱体的X,Y位置-射线-三角形-与空间的交点[-1,1] [-1,1]

时间:2019-02-26 15:37:45

标签: c++ opengl graphics 3d raytracing

我正在将图块贴图渲染到fbo,然后将结果缓冲区移动到纹理并将其渲染到FSQ上。然后从鼠标单击事件中,我得到了屏幕坐标并将其移至剪辑空间[-1,1]:

    glm::vec2 posMouseClipSpace((2.0f * myCursorPos.x) / myDeviceWidth - 
                 1.0f, 1.0f - (2.0f *  myCursorPos.y) / myDeviceHeight);

我的程序中有逻辑,基于这些坐标,它将在纹理上选择特定的图块。

enter image description here

现在,转到3D,我将使用在上一步中使用的FBO为半圆柱体构造纹理:

enter image description here

在这种情况下,我使用的射线三角形交点以半径r和高度h击中圆柱体。想法是将此交点移动到空间[-1,1],因此我可以将逻辑保留在程序中以选择图块

我使用Möller-Trumbore算法来检查射线照射到圆柱体上的点。假设相交的点是(x,y)(不确定该点是在三角形,物体还是世界空间中。显然是世界空间)。 我想将该点转换为空间x:[-1,1],y [-1,1]。

我知道我的圆柱体的高度,它是圆柱体弧长的四分之一:

cylinderHeight = myRadius *(PI / 2);

因此可以在[-1,1]空间中设置Y轴上的点:

vec2.y = (2.f * (intersectedPoint.y - myCylinder->position().y) ) / 
         (myCylinder->height()) - 1.f

那很好用。

但是,如何计算取决于2个变量x和z的水平轴?

当前,我的圆柱体的半径为1,因此巧合的是,原点设置的半圆柱体将从X轴上的(-1,1)开始,这使我认为它是[-1,1]空间,但是事实并非如此。 我的下一个方法是使用半圆的弧长 s = r * PI ,然后将该值插入方程式:

vec2.x = (2.f * (intersectedPoint.x - myCylinder->position().x) ) / 
             (myCylinder->arcLength()) - 1.f

但很明显,它在负方向上偏离了1个单位。

感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

根据您的描述,您似乎想将世界空间相交坐标转换为其对应的归一化纹理坐标。

为此,您还需要Z坐标,因为必须有两个“水平”坐标。但是,不需要需要弧长。

使用intersectedPoint的相对X和Z坐标,使用atan2计算极角,然后除以PI(半圆弧的角度范围):

vec2.x = atan2(intersectedPoint.z - myCylinder->position().z,
               myCylinder->position().x - intersectedPoint.x) / PI;