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

X,Y position of semi cylinder - ray - triangle- intersection to space [-1,1] [-1,1]

我正在将瓦片贴图渲染到 fbo,然后将生成的缓冲区移动到纹理并将其渲染到 FSQ 上。然后从鼠标点击事件中,我得到了屏幕坐标并将它们移动到 clip space [-1,1]:

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

我的程序有逻辑,基于这些坐标,它 select 是纹理上的特定图块。

现在,转到 3D,我正在使用上一步中使用的 FBO 对半圆柱体进行纹理处理:

在这种情况下,我使用的是射线-三角形交点,该交点与半径为 r、高度为 h 的圆柱体相交。我的想法是将这个交点移动到 space [-1,1] 这样我就可以将程序的逻辑保持在 select tiles

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

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

圆柱体高度 = myRadius * (PI/2);

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

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

而且效果很好。

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

目前,我的圆柱体的半径是 1,所以巧合的是,在原点设置的半圆柱体将从 X 轴上的 (-1 ,1) 开始,这让我认为它是 [-1,1] space,但事实证明不是。 我的下一个方法是使用半圆的弧长 s =r * PI 然后将该值代入等式:

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

但很明显它在负方向上下降了 1 个单位。

感谢您的帮助。

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

为此你还需要 Z 坐标,因为必须有 两个 "horizontal" 坐标。但是您不需要弧长。

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

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