如何在圆柱体表面计算法线?

6

我正在开发一个光线追踪器,现在要将圆柱体添加到场景中。我卡在了找到光线碰撞点的表面法向量这一步。为了实现漫反射光照效果,我需要它。目前,我已经有了相机光线与圆柱体相交处的 3D 点以及实际的圆柱体,圆柱体由轴线上的一个点、表示轴线方向的向量和半径定义。简而言之,我的问题是,在给定圆柱体碰撞点、半径、轴上一点和轴方向向量的情况下,如何找到该点的法向量。


你在使用Unity吗?还是用的什么编程语言? - AMACB
我正在使用C语言,但在这种情况下它应该是无关紧要的。 - Rpreda
一些编程语言可能有内置函数,这些函数可能会很有用。 - AMACB
1
好的,没问题 :) 但是我还停留在老旧的C语言中 :)) - Rpreda
2个回答

6

圆柱体法向量始于圆柱体的中心线,与光线相交处的z轴高度相同,在径向相交点结束。将其标准化后即可得到单位法向量。

如果圆柱体的中心线不沿场景的全局z方向,则必须转换为圆柱体坐标系,计算法向量,然后将其转换回全局坐标系。


所以基本上我只是计算法线,就好像圆柱体完全垂直一样,然后只需在该向量上使用旋转矩阵将其旋转到圆柱的角度? - Rpreda
圆柱坐标系中的法向量;转换为全局坐标系。可能存在多个连续的旋转。 - duffymo
非常顺利的工作 :) 感谢您的帮助! - Rpreda

3

有三种可能的情况:

  1. hit_pt在圆柱体的顶盖上:
    if (length(hit_pt - cy.top_center) < cy.radius)
           surface_normal = cy.ori;

2. hit_pt 在圆柱体的底盖上。
    if (length(hit_pt - cy.bottom_center) < cy.radius)
            surface_normal = -1 * cy.ori;
  • 击中点位于圆柱的侧面。我们可以使用点积来找到圆柱中心线上的点“pt”,使得向量(hit_pt - pt)垂直于圆柱的方向。
  •     t = dot((hit_pt - cy.bottom_center), cy.ori); // cy.ori should be normalized and so has the length of 1.
        pt = cy.bottom_center + t * cy.ori;
        surface_normal = normalize(hit_pt - pt)));
    

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接