Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.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
Vector 如何计算三维空间中给定两个向量的反射角?_Vector_Geometry_Angle_Algebra - Fatal编程技术网

Vector 如何计算三维空间中给定两个向量的反射角?

Vector 如何计算三维空间中给定两个向量的反射角?,vector,geometry,angle,algebra,Vector,Geometry,Angle,Algebra,我想计算两个向量a和b之间的角度。假设它们位于原点。这可以通过 theta = arccos(a . b / |a| * |b|) 但是,arccos给了你[0,pi]中的角度,也就是说,它永远不会给你一个大于180度的角度,这就是我想要的。那么你怎么知道向量什么时候超过了180度?在2D中,我会简单地让其中一个向量上的y分量的符号确定向量所在的象限。但是在3D中最简单的方法是什么呢 编辑:我想把这个问题概括一下,但我们开始吧。我正在用c语言编程,我用来获取角度的代码是θ=acos(点(a,b

我想计算两个向量a和b之间的角度。假设它们位于原点。这可以通过

theta = arccos(a . b / |a| * |b|)
但是,arccos给了你[0,pi]中的角度,也就是说,它永远不会给你一个大于180度的角度,这就是我想要的。那么你怎么知道向量什么时候超过了180度?在2D中,我会简单地让其中一个向量上的y分量的符号确定向量所在的象限。但是在3D中最简单的方法是什么呢


编辑:我想把这个问题概括一下,但我们开始吧。我正在用c语言编程,我用来获取角度的代码是θ=acos(点(a,b)/mag(a)*mag(b))那么你如何通过编程确定方向呢?

这在2D中工作,因为你有一个定义旋转的平面

如果要在三维中执行此操作,则不存在此类隐式二维平面。您可以将三维坐标变换为穿过所有三个点的二维平面,并在此平面内进行计算


但是,当然,平面有两个可能的方向,这将影响哪个角度大于或小于180

严格来说,两个3D向量之间总是有两个角度-一个低于或等于180,另一个高于或等于180。Arccos给你一个,你可以从360减去另一个。这样想:想象两条线相交。这里有4个角度-一个值的2个,另一个值的2个。两条线之间的夹角是多少?没有单一的答案。彼此彼此。如果没有某种额外的标准,理论上,您无法判断应该考虑两个角度值中的哪一个


编辑:所以你真正需要的是一个固定方向的任意示例。这里有一个:我们从正Z方向看。如果两个向量之间的平面包含Z轴,则我们从正Y方向观察。如果平面是YZ,我们从正X方向看。我将考虑如何用坐标形式表示,然后再次编辑。

您可以使用的一种解决方案:
实际上,你需要做的是创建一个向量与之共面的平面

得到两个向量的叉积将创建一个平面,然后你得到这个平面的法线,你可以得到这个向量和你需要得到符号角度的向量之间的角度,你可以使用这个角度来确定符号。
如果角度大于90度,则该角度低于创建的平面;低于90度,且高于90度。
根据计算成本,此阶段可以使用点积而不是角度

只需确保始终按向量的相同顺序计算法线

如果使用XYZ轴,这将更容易使用,这正是您要比较的,因为您已经拥有平面所需的向量

可能有更有效的解决方案,但这是我想出的一个

编辑:已创建向量的澄清
a X b=p
。这与
a
b
都垂直。 然后,执行以下任一操作:
a X p
b X p
来创建另一个向量,该向量是由这两个向量创建的平面的法线。向量的选择取决于你试图找到哪个向量的角度。

我提出了以下解决方案,利用了两个向量的叉积的方向变化:

  • 制作一个向量,并将其规格化。该向量垂直于a和b所跨越的平面

  • 每当计算新角度时,将其与旧法线进行比较。在比较中,将旧法线和当前法线视为点,并计算它们之间的距离。如果该距离为2,则为正常距离(即叉积a X b已翻转)


  • 您可能需要为距离设置一个阈值,因为翻转后的距离可能小于2,这取决于向量a和b的方向以及更新角度的频率。

    @Reimund-一道很棒的数学问题。然而,stackoverflow是一个只针对编程问题的论坛。投票结束,脱离主题。但由于编程与数学密切相关,特别是在算法方面,它仍然有效[IMO]。否则,为什么大部分的CS课程也有数学课呢?只是一个小小的观察,我认为你的编辑可能有问题,应该包括名词周围的名词。应该是这样的:acos(dot(a,b)/(mag(a)*mag(b)),我实际上已经走了这条路,但还没有完全实现。我希望有一个更简单的解决办法。我要做的是将向量a和b乘以C的倒数,其中C=[a;ax(axb);axb]得到u和v。我期望u和v的z分量为零,但它们没有。也许我的C矩阵定义不正确?你确定这行得通吗?我以前试过,得到的角度总是90度(根据叉积的定义)。你能详细说明一下如何使用dot产品解决这个问题吗?现在还不清楚。我想要a和b之间有符号的角度,如果我理解正确,我应该检查a和(a X p)之间的角度是否小于或大于90?不,在这种情况下,你应该做
    a
    (b X p)
    ,因为
    a
    从定义上看是垂直于
    a X p
    的,似乎是a和(b X p)之间的角度始终小于90:/噢,废话,你说得对-当
    a
    位于另一侧时,它将导致生成的
    p
    的方向翻转,从而导致结果正常。我想需要更多关于
    a
    b
    的性质的信息,看看是否可以生成一个常数平面……我的问题是关于“额外标准”的!你告诉我:)在三维空间中有两种定义方向的方法。你的问题的措辞意味着当你看到它时你知道它;但是你没有