计算镜面角度的解析方法

zac*_*aro 5 c++ graphics opencv raytracing computer-vision

我在3D空间中有固定光线LrM可以围绕固定点旋转的镜子 Mrot,这个点不在镜子的同一平面上,换句话说,镜面Mrot与以固定半径为中心的球体相切d.通过该配置,我想找到一个方程,该方程接收点P作为参数,并在3D空间中随着镜子的旋转而产生结果.

我们可以认为镜面没有边界(无限平面),它的旋转没有限制.此外,镜子仅反射在其旋转点的相对侧.

在图象两种情况用不同的输入点P1P2,与它们各自的溶液的角度alpha1alpha2.图片是2D以简化图纸,真实案例是3D. FSD

目前我正在随机旋转计算与镜面的交点,然后计算光线反射并查看距离我想要到达的点(P)的距离.最后迭代一些条件改变旋转直到匹配.

显然这是一种矫枉过正,但我​​无法弄清楚如何以分析方式对其进行编码.

有什么想法吗?

注意:我注意到如果镜子围绕它的平面中的一个点(Mrot)旋转并且射线光到达那个点(Mrot)我可以很容易地计算出镜子的角度,但不幸的是不是我的情况.

PBS*_*PBS 5

首先请注意,这里只有一个参数,即t沿着光线射到镜子的距离.

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

  1. 反射发生的点.
  2. 入射和反射光线的矢量.
  3. 镜子的法向量,通过取归一化入射和反射向量的平均值得到.与1一起,你现在知道镜子的平面.
  4. d镜子到旋转点的距离.

现在的问题是选择t取得d所需的价值.这归结为一个octic多项式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);
}
Run Code Online (Sandbox Code Playgroud)

现在calc_d_from_t(t) = d转到您最喜欢的根查找器,确保找到根t > 0.任何半合适的根查找器(例如Newton-Raphson)应该比您当前的方法快得多.


[1]即涉及算术运算,第n个根和系数的公式.
[2]除非octic因素相同,否则可能将问题减少到四分之一.