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

问题描述 投票:1回答:1

我正在将一个平铺贴图渲染到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);

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

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个单位消失。

我很感激帮助。

c++ opengl graphics 3d raytracing
1个回答
1
投票

根据您的描述,您似乎希望将世界空间交点坐标转换为其对应的标准化纹理坐标。

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

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

vec2.x = atan2(intersectedPoint.z - myCylinder->position().z,
               myCylinder->position().x - intersectedPoint.x) / PI;
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.