我一直关注此tutorial进行碰撞检测,其中它使用2d三重积来构造垂直线。使用从 c 0 到 c 1 的矢量 A 和矢量 B 从 c 0 到原点。声称是 A,B,A 的三重积与 A 垂直并且在原点方向上。我不明白为什么这样可行或者如何在2D中使用交叉产品。
答案 0 :(得分:1)
我看了the implementation,我绝对不会称之为triple product。通常的三重产品使用交叉积然后是点积,而这里是连续的两个交叉积,通过在2d向量上附加零来构造3d向量。那会发生什么?
A×B =(Ax,Ay,0)×(Bx,By,0)=(0,0,Ax∙By-Ay∙Bx)
......×A =(Ax∙By-Ay∙Bx)∙(Ay,-Ax,0)
所以结果是(Ay,-Ax)的一些倍数。这确保了这确实与A垂直。并且如果A和B是平行的,则多次改变符号。因此,对于A和B不平行,一个方向将给出一个方向而另一个方向将给出另一个方向。如果您不想更深入地思考,请使用实验来确定哪个是哪个。
作为旁注,我不会这样做。相反,我会依赖于经典的方向谓词。但是我没有读过所有那篇文章,所以也许有理由不这样做。如果您想了解更多信息,请注意决定因素
|Ax Bx Cx|
|Ay By Cy|
| 1 1 1|
(顺便说一下等于三重乘积(A×B)∙C如果用1而不是0加)等于由A,B形成的三角形的定向区域的两倍,所以这个标志告诉你三角形的方向。你可以使用这个,例如计算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";
}