我在3D空间中有一个固定的光线Lr和一个可以围绕固定点M旋转的镜子Mrot,此点不在镜子的同一平面上,换言之,镜子平面与以Mrot为中心的球面相切具有固定半径d。通过这种配置,我想找到一个方程,该方程将点P接收为参数,并随着3D空间中镜子的旋转而产生结果。

我们可以认为镜像平面没有边界(无限平面),并且其旋转没有限制。而且,反射镜仅在其旋转点的相反侧反射。

图中有两种情况,它们的输入点为P1P2不同,它们的解决角度分别为alpha1alpha2。图片是2D的,以简化图纸,实际情况是3D的。

目前,我正在以随机旋转的方式计算与镜平面的交点,然后计算光线反射并查看距我要到达的点(P)有多远。最后,在某种条件下进行迭代以更改旋转,直到匹配为止。

显然,这太过分了,但是我无法弄清楚如何以解析方式对其进行编码。

有什么想法吗?

注意:我注意到,如果反射镜绕其平面中包含的一个点(Mrot)旋转并且光线到达该点(Mrot),我可以轻松计算出反射镜角度,但是不幸的是,我的情况并非如此。

最佳答案

首先要注意的是,这里只有一个参数,即沿着它撞击镜子的光线的距离t

对于t的任何测试值,请按顺序计算

  • 发生反射的点。
  • 入射光线和反射光线的 vector 。
  • 镜像的法线 vector ,通过取归一化的入射和反射 vector 的平均值来找到。与1一起,您现在知道了镜子的平面。
  • 镜子到旋转点的距离d

  • 现在的问题是选择t以使d达到所需的值。这归结为t中的八项多项式,因此没有解析公式[1]和,唯一的解决方案是迭代。[2]。

    这是一个代码示例:
    vec3 r;   // Ray start position
    vec3 v;   // Ray direction
    vec3 p;   // Target point
    vec3 m;   // Mirror rotation point
    
    double calc_d_from_t(double t)
    {
        vec3 reflection_point = r + t * v;
        vec3 incident         = normalize(-v);
        vec3 reflected        = normalize(p - reflection_point);
        vec3 mirror_normal    = normalize(incident + reflected);
        return dot(reflection_point - m, mirror_normal);
    }
    

    现在将calc_d_from_t(t) = d传递到您最喜欢的根查找器,确保使用t > 0查找根。任何半体面的寻根工具(例如Newton-Raphson)应该比您目前的方法快得多。

    [1]一个包含算术运算,第n个根和系数的公式。
    [2]除非八达通因式分解相同,否则有可能将问题简化为四次。

    关于c++ - 镜面角度的解析方法,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31333630/

    10-11 18:17