如何计算圆柱表面的法线?

How can I compute normal on the surface of a cylinder?

我正在研究光线追踪器,然后开始向场景中添加圆柱体。我坚持的一点是在光线击中的点找到表面法向量。我需要这个才能进行漫射照明。我此时拥有的是相机光线撞击圆柱体的 3d 点和用中心轴上的一个点定义的实际圆柱体,向量表示轴的方向和半径。所以总结一下我的问题,如何在具有圆柱体命中点,半径,其轴上的点和轴的方向向量的点中找到法向量?

圆柱法向量从圆柱的中心线开始,在光线与圆柱相交的点的相同 z 高度处,结束于径向交点。对其进行归一化,你就有了单位法向量。

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

可能存在三种情况:

  1. hit_pt 在气缸的顶盖上:
    if (length(hit_pt - cy.top_center) < cy.radius)
           surface_normal = cy.ori;
  1. hit_pt 在圆柱体的底盖上:
    if (length(hit_pt - cy.bottom_center) < cy.radius)
            surface_normal = -1 * cy.ori;
  1. hit_pt 在圆柱体的侧面。我们可以用点积求出圆柱体中心线上的点'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)));