Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/extjs/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 计算反射镜角度的解析法_C++_Opencv_Graphics_Computer Vision_Raytracing - Fatal编程技术网

C++ 计算反射镜角度的解析法

C++ 计算反射镜角度的解析法,c++,opencv,graphics,computer-vision,raytracing,C++,Opencv,Graphics,Computer Vision,Raytracing,我在3D空间中有一条固定光线Lr和一个可以围绕固定点Mrot旋转的镜子M,该点不在镜子的同一平面上,换句话说,镜子平面与以Mrot为中心的球体相切,半径固定d。通过这种配置,我想找到一个方程,它接收点P作为参数,并在3D空间中随着镜子的旋转而产生结果 我们可以认为镜面没有边界(无限平面),它的旋转是没有限制的。此外,反射镜仅在其旋转点的另一侧反射 图中有两种情况,输入点不同,分别为P1和P2,其各自的解决方案角度为alpha1和alpha2。图片是二维的,以简化图纸,真实情况是三维的。 此时,

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

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

图中有两种情况,输入点不同,分别为
P1
P2
,其各自的解决方案角度为
alpha1
alpha2
。图片是二维的,以简化图纸,真实情况是三维的。

此时,我正在计算与随机旋转的镜像平面的交点,然后计算光线反射,看看距离我想要到达的点(p)有多远。最后,使用某些条件迭代,更改旋转,直到匹配为止

很明显,这是一种过分的做法,但我不知道如何用分析的方式编写代码

有什么想法吗


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

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

  • 开始

    • 镜像在恒定距离内围绕Mrot旋转,创建圆(3D中的球体)
    • 所以计算Lr和球体的第一个交点
    • 或者,如果未找到交点,则在球体上找到距离Lr最近的点
    • n0
      法线计算为
      Lr
      和从交点到
      P的红线之间的半角
    • 这是后视镜的起始位置
  • 将后视镜(aqua)置于
    n0
    角度

    • 计算
      Lr的反射
    • 然后计算半角
      da0
      这是新迭代的步骤
  • da0
    添加到
    n0
    角度,并将后视镜放置在此新角度位置

    • 计算
      Lr的反射
    • 然后计算半角
      da1
      这是新迭代的步骤
  • 循环子弹3直到

    • da(i)
      足够小了
    • 已达到最大迭代次数
  • [附注]

    • 这应该比随机/线性探测更快地收敛到解
    • 距离反射镜越远(或旋转半径越小),收敛速度越快
    • 不确定这个问题的解析解是否存在,它看起来会导致超越系统…

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

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

  • 反射发生的点
  • 入射光线和反射光线的矢量
  • 反射镜的法向量,取归一化入射向量和反射向量的平均值。加上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\u d\u from_t(t)=d
    传递给您喜爱的根查找器,确保使用
    t>0
    查找根。任何半正派的根查找器(如Newton Raphson)都应该比当前的方法快得多


    [1] 即,涉及算术运算、n次根和系数的公式。

    [2] 除非八分位数分解相同,否则可能会将问题归结为四分位数。

    能否详细说明镜子的移动方式?它是否像斯佩克特假设的球体表面?你是否假设只有平面的一侧反射?@SebastianCabot镜子相对于点
    Mrot
    旋转,所有可能的旋转都衍生自镜面到点
    Mrot
    的共有距离。就像@Spektre假设的那样。反射面是反射镜的背面,面对着
    Mrot
    像@Spektre建议的那样。到旋转点的距离有什么不同。他只需要找到交点和法线。你能进一步解释一下吗。这是非常重要的interesting@SebastianCabot:就我所理解的问题而言,M被限制在距离Mrot一定距离的地方。如果没有此约束,您可以安排镜像在任意点将Lr反射到P,因此问题是找到与旋转点距离约束相关的反射点。是的,这是正确的。但是,约束是否足以让您找到解决方案?我仍在试图弄明白,我想更好地理解你的推理。不管我们需要解决的约束是什么:Rvec=2*dot(Nvec,IVec)*Nvec-IVec。由于已知Psource和Pdest,我们可以进一步将其简化为-Pdest=2*(dot(NVec,IVec))*NVec-PSrc。如果我们使用规范化向量,我想我们可以写:norm(PSrc)-norm(Pdst)=2*cos(ang(Nvec,IVec))*norm(n)-所以我们仍然需要根据您指定的约束来寻找角度,我不明白您打算怎么做?我们不需要知道cos(ang(Nvec,IVec)),因为它只是n的一个规范化常数。我没有