计算2D矢量叉积
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了计算2D矢量叉积相关的知识,希望对你有一定的参考价值。
来自维基百科:
交叉乘积是对三维欧几里德空间中的两个向量的二元运算,其导致另一个向量垂直于包含两个输入向量的平面。
鉴于该定义仅在三个(or seven, one and zero)维度中定义,如何计算两个2d向量的叉积?
我见过两个实现。一个返回一个新的向量(但只接受一个向量),另一个返回一个标量(但是是两个向量之间的计算)。
实现1(返回标量):
float CrossProduct(const Vector2D & v1, const Vector2D & v2) const
{
return (v1.X*v2.Y) - (v1.Y*v2.X);
}
实现2(返回向量):
Vector2D CrossProduct(const Vector2D & v) const
{
return Vector2D(v.Y, -v.X);
}
为什么不同的实施?我将使用标量实现?我将使用矢量实现?
我问的原因是因为我自己编写了一个Vector2D类,并且不知道使用哪种方法。
实现1返回将由输入向量的常规3D叉积产生的向量的大小,将其Z值隐式地取为0(即,将2D空间视为3D空间中的平面)。 3D十字产品将垂直于该平面,因此具有0个X和Y分量(因此返回的标量是3D叉积矢量的Z值)。
注意,由3D叉积产生的矢量的幅度也等于两个矢量之间的平行四边形的面积,这给出了实现1的另一个目的。此外,该区域已签名,可用于确定从V1到V2的旋转是以逆时针还是顺时针方向移动。还应注意,实现1是从这两个向量构建的2×2矩阵的决定因素。
实现2返回垂直于仍在同一2D平面中的输入矢量的矢量。不是经典意义上的交叉产品,而是“给我一个垂直向量”的意义。
请注意,3D欧几里德空间在交叉乘积操作下是关闭的 - 也就是说,两个3D矢量的叉积返回另一个3D矢量。上述两种2D实现都与这种或那种方式不一致。
希望这可以帮助...
简而言之:它是数学黑客的简写符号。
很长的解释:
你不能在2D空间中使用向量来交叉产品。那里没有定义操作。
然而,通常有意义的是评估两个矢量的叉积,假设通过将它们的z坐标设置为零来将2D矢量扩展到3D。这与在xy平面上使用3D矢量相同。
如果以这种方式扩展向量并计算这种扩展向量对的叉积,您会注意到只有z分量具有有意义的值:x和y将始终为零。
这就是为什么结果的z分量通常只是作为标量返回的原因。该标量例如可以用于在2D空间中找到三个点的绕组。
从纯粹的数学观点来看,2D空间中的交叉积不存在,标量版本是黑客,而返回2D矢量的2D交叉产品完全没有意义。
交叉积的另一个有用特性是它的大小与两个向量之间角度的正弦值有关:
| a x b | = | a | 。 | B | 。正弦(THETA)
要么
正弦(theta)= | a x b | /(| a |。| b |)
因此,在上面的实现1中,如果事先知道a
和b
是单位向量,那么该函数的结果正好是sine()值。
实现1是两个向量的perp点积。我所知道的2D图形的最佳参考是优秀的Graphics Gems系列。如果您正在进行临时2D工作,那么拥有这些书非常重要。第四卷有一篇名为“Perp Dot产品的乐趣”的文章,它经历了很多用途。
perp点积的一个主要用途是获得两个向量之间角度的缩放sin
,就像点积返回角度的缩放cos
一样。当然,您可以一起使用点积和perp点积来确定两个向量之间的角度。
Here是一篇文章,here是Wolfram Math World的文章。
我在我的计算中使用二维交叉乘积来找到一个物体的新的正确旋转,该物体在相对于其质心的任意点处被力矢量作用。 (标量Z一。)
有用的2D矢量运算是返回标量的叉积。我用它来看看多边形中的两个连续边是向左还是向右弯曲。
来自Chipmunk2D来源:
/// 2D vector cross product analog.
/// The cross product of 2D vectors results in a 3D vector with only a z component.
/// This function returns the magnitude of the z value.
static inline cpFloat cpvcross(const cpVect v1, const cpVect v2)
{
return v1.x*v2.y - v1.y*v2.x;
}
以上是关于计算2D矢量叉积的主要内容,如果未能解决你的问题,请参考以下文章