我在 3D 空间中有一个固定光线 Lr
和一个可以围绕固定点 Mrot
旋转的镜子 M
,这一点不在镜子的同一平面上,换句话说,镜子平面与以 Mrot
为中心且半径固定 d
的球体相切。使用该配置,我想找到一个方程式,该方程式接收点 P
作为参数,并根据镜子在 3D 空间中的旋转得出结果。
我们可以认为镜像平面没有边界(无限平面)并且它的旋转没有限制。此外,镜子仅在其旋转点的另一侧反射。
图中是输入点P1
和P2
不同的两种情况,分别有解角alpha1
和alpha2
。图片为2D,简化绘图,真实案例为3D。
此刻我在随机旋转计算与镜面的交点,然后计算光线反射,看看离我想到达的点(P)有多远。最后迭代一些条件改变旋转直到它匹配。
显然这是一种矫枉过正,但我无法弄清楚如何以分析方式对其进行编码。
有什么想法吗?
注意:我注意到如果镜子围绕其平面中的一个点 (Mrot) 旋转并且光线到达该点 (Mrot),我可以轻松计算出镜子角度,但不幸的是我的情况并非如此。
最佳答案
首先请注意,这里只有一个参数,即沿光线到达镜子的距离t
。
对于t
的任意测试值,依次计算
- 反射发生的点。
- 入射光线和反射光线的 vector 。
- 镜子的法 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/