1

我一直在关注本教程进行碰撞检测,其中它使用 2d 三元积来构造垂直线。使用从c 0c 1的向量A和从c 0到原点的向量B。声称是A,B,A的三重乘积垂直于A并且在原点的方向上。我不明白为什么会这样,也不明白叉积是如何在 2D 中使用的。

4

1 回答 1

1

我查看了实现,我绝对不会将其称为三重产品。通常的三重乘积使用叉积然后是点积,而这里是连续的两个叉积,通过在 2d 向量上附加一个零来构造 3d 向量。那么会发生什么?

A × B = (Ax,Ay,0) × (Bx,By,0) = (0,0,Ax∙By−Ay∙Bx)
… × A = (Ax∙By−Ay∙Bx)∙(Ay, -斧头,0)

所以结果是 (Ay,−Ax) 的某个倍数。这确保了这确实与 A 垂直。并且如果 A 和 B 平行,则多个变化完全标志。因此,对于不平行的 A 和 B,一个方向将给出一个方向,而另一个方向将给出另一个符号。如果您不想更深入地思考,请使用实验来决定哪个是哪个。

附带说明一下,我不会以这种方式做事。相反,我会依赖经典的方向谓词。但是我还没有阅读所有那篇文章,所以也许有理由不这样做。如果您想了解更多信息,请注意行列式

|Ax Bx Cx|
|Ay By Cy|
| 1  1  1|

(顺便说一下,如果你用 1 而不是 0 来增加,它等于三倍积 (A×B)∙C)等于由 A、B、C 形成的三角形的定向面积的两倍。所以这个符号告诉你关于所述三角形的方向。例如,您可以使用它来计算符号 OAB、OBC、OCA。如果他们都同意包含来源。请注意,行列式 |OAB| 之类的东西 = Ax∙By−Ay∙Bx容易计算。

var oab = Math.sign(a.x*b.y - a.y*b.x);
var obc = Math.sign(b.x*c.y - b.y*c.x);
var oca = Math.sign(c.x*a.y - c.y*a.x);
if (Math.abs(oab + obc + oca) == 3) {
  return "contains origin";
}
if (oab * obc * oca == 0) {
  return "origin is on the boundary";
}
var abc = Math.sign(a.x*b.y + b.x*c.y + c.x*a.y -
                    a.x*c.y - b.x*a.y - c.x*b.y);
if (oab != abc) {
  return "outside line ab";
} else if (obc != abc) {
  return "outside line bc";
} else {
  return "outside line ac";
}
于 2017-06-29T00:43:38.303 回答