c++ - 反射镜角度的解析法

标签 c++ opencv graphics computer-vision raytracing

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

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

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

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

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

有什么想法吗?

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

最佳答案

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

对于t的任意测试值,依次计算

  1. 反射发生的点。
  2. 入射光线和反射光线的 vector 。
  3. 镜子的法 vector ,它是通过取归一化入射 vector 和反射 vector 的平均值得到的。连同 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] 除非八进制因式分解相同,否则可能会将问题简化为四次。

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

相关文章:

c++ - 如何在代码中获取函数名称

C++ scanf %la 返回 0

c++ - OpenCV Mat 数组访问,哪种方式最快,为什么?

javascript - 如何在不使用外部库的情况下使用 JavaScript 绘制折线图

c++ - 跟踪 gcc 编译以及哪些代码减慢了它的速度

c++ - 在 C++ 头文件中定义常量变量

opencv - 图像坐标到世界坐标opencv

python - 通过使用 cv2.VideoCapture 降低 fps

java - 我怎样才能让这个 JButton 重绘我的 Die Graphics?

java - 移动具有渐变填充的矩形