标签:
①: 如果两个图形恰好接触, 之后EPA得到的嵌入向量会是零向量. 只要把原点恰在闵可夫斯基差边界上的情况也排除当作不接触就能解决.
②: 如果原点恰好落在单纯形的AB边上, 之后得到的搜索方向会是零向量, 最后得到的单纯形不再是三角形, 而是一条线段. 此时仅用来判断是否重叠的GJK依然能正常判断, 但之后的EPA就不能正常工作了. 个人的解决方法是强行用AB的垂直向量当作搜索方向找出点C以组成三角形. 之后的EPA得到的嵌入向量可能微有偏差, 但还在接受范围内.
isIntersect: function () {
var dir = new pngx.Vector2D(1, 1),
simplexA,
simplexB,
simplexC;
simplexA = this.getSupportPoint(dir);
if (simplexA.dot(dir) <= 0) {
return false;
}
dir = simplexA.negate();
simplexB = this.getSupportPoint(dir);
if (simplexB.dot(dir) <= 0) {
return false;
}
var ab = simplexB.sub(simplexA);
dir = pngx.Vector2D.tripleProduct(ab, simplexA.negate(), ab);
for (var i = this.maxIterations; i--;) {
if (dir.isZero()) {
this._simplexA = simplexA;
this._simplexB = simplexB;
dir = simplexB.sub(simplexA).vertical();
this._simplexC = this.getSupportPoint(dir); //原点恰好在AB上使得搜索方向是零向量, 强行选出一个垂直于AB的方向找出simplex的第三点
return true;
}
simplexC = this.getSupportPoint(dir);
if (simplexC.dot(dir) <= 0) { //小于号改为小于等于, 原点恰在边界上 时也排除
return false;
}
var ba = simplexA.sub(simplexB),
ac = simplexC.sub(simplexA),
bc = simplexC.sub(simplexB),
acPerp = pngx.Vector2D.tripleProduct(ac, ba.negate(), ac),
bcPerp = pngx.Vector2D.tripleProduct(bc, ba, bc);
if (acPerp.dot(simplexA) > 0) {
simplexB = simplexC;
dir = acPerp.negate();
} else if (bcPerp.dot(simplexB) > 0) {
simplexA = simplexC;
dir = bcPerp.negate();
} else {
this._simplexA = simplexA;
this._simplexB = simplexB;
this._simplexC = simplexC;
return true;
}
}
return false;
}
标签:
原文地址:http://www.cnblogs.com/pngx/p/4461577.html