反射镜角度的解析法

Analytic method for calculate a mirror angle

我在3D中有一个space固定的光线Lr和一个可以围绕固定点Mrot旋转的镜子M,这个点不在镜子的同一平面,换句话说,镜子平面与以 Mrot 为中心、半径固定 d 的球体相切。使用该配置,我想找到一个方程式,该方程式接收点 P 作为参数,并随着 3D space.

中镜子的旋转而产生结果

我们可以认为镜像平面是没有边界的(无限平面),它的旋转是无限的。另外,镜子只在其旋转点的另一侧反射。

图中是输入点P1P2不同的两种情况,分别有解角alpha1alpha2。图片为2D,简化绘图,真实案例为3D。

此刻我正在计算随机旋转与镜面的交点,然后计算光线反射,看看离我想到达的点(P)有多远。最后迭代一些条件改变旋转直到它匹配。

显然这是一种矫枉过正,但我​​不知道如何以分析方式对其进行编码。

有什么想法吗?

注意:我注意到,如果镜子围绕其平面中的一个点 (Mrot) 旋转并且光线到达该点 (Mrot),我可以轻松计算出镜子角度,但不幸的是不是我的案件。

我会把它作为两个独立的平面问题来做(一个在 xy 平面上,第二个在 xz 或 yz 平面上)。我首先想到的是这个迭代过程:

  1. 开始

    • 镜子以恒定距离围绕 Mrot 转动,形成圆(3D 球体)
    • 所以计算 Lr 和球体的第一个交点
    • 如果没有找到交点,则在球体上找到离 Lr 最近的点
    • 计算 n0 法线为 Lr 和红线从交点到 P
    • 的半角
    • 这是镜像起始位置
  2. 将镜子(水绿色)放置到 n0 角度

    • 计算 Lr
    • 的反射
    • 并计算半角da0这是新迭代的步骤
  3. da0 添加到 n0 角度并将镜子放置到这个新的角度位置

    • 计算 Lr
    • 的反射
    • 并计算半角da1这是新迭代的步骤
  4. 循环项目符号 3 直到

    • da(i)够小
    • 达到最大迭代次数

[备注]

  • 这应该比 random/linear 探测
  • 更快地收敛到解决方案
  • P离镜子越远(或旋转半径越小)收敛越快
  • 不确定这个问题的解析解是否存在它看起来会导致超越系统...

首先注意这里只有一个参数,即光线到达镜子的距离t

任意测试值t,依次计算

  1. 发生反射的点。
  2. 入射光线和反射光线的矢量。
  3. 镜子的法向量,通过取归一化入射向量和反射向量的平均值得到。连同 1,你现在知道镜子的平面了。
  4. 镜子到旋转点的距离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] 除非八进制因式分解相同,否则可能会将问题简化为四次。