问题描述
我正在学习用于 2D 碰撞和响应的分离轴定理。我想支持与凹多边形的碰撞,所以我正在使用 earcut 对多边形进行三角剖分并测试每个三角形。
不幸的是,它似乎仍然将凹多边形视为凸多边形,例如,给定坐标 (0,0)
、(0,50)
、(40,50)
和 (10,40)
,碰撞表现得好像 (10,40)
点不存在,有效地使它成为一个三角形。我检查了三角坐标,它们看起来很正常:[1,3,2,1]
(每个数字代表点的索引)。
此外,我的 SAT 实现在发现不重叠的“阴影”时返回 false,但通过检查每个三角形相互之间的关系,单个三角形在其父多边形发生碰撞时可能不重叠。响应中也存在类似的问题,我抓住了最小的重叠差异并将碰撞器推回,但与单个三角形的最小重叠可能并不代表真正的重叠量。
我该如何解决这两个问题?
jsfiddle:https://jsfiddle.net/ay51n4we/
注意:我在jsfiddle的末尾包含了earcut库,我的代码是第291行
三角剖分
triangulate(){
let pvertices = [];
for(let v of this.vertices){
pvertices.push(v.x,v.y);
}
this.tpoints = earcut(pvertices); // triangulated vertices
this.tsub = []; // triangulated polygons for collision
for(let i = 0; i < this.tpoints.length; i+=3){
this.tsub.push([this.vertices[this.tpoints[i]],this.vertices[this.tpoints[i+1]],this.vertices[this.tpoints[i+2]]]);
}
}
碰撞检测
let sprite1 = this;
let sprite2 = cand;
for (let sprite = 0; sprite < 2; sprite++) {
if (sprite == 1) {
// flip to avoid repetitive code
sprite1 = cand;
sprite2 = this;
}
for(let s = 0; s < sprite1.tsub.length; s++){
for (let a = 0; a < sprite1.tsub[s].length; a++) {
const b = (a + 1) % sprite1.tsub[s].length;
// normal to sprite edge (axis projection)
const ap = new Vector(-(sprite1.tsub[s][b].y - sprite1.tsub[s][a].y),sprite1.tsub[s][b].x - sprite1.tsub[s][a].x);
// find min max for both sprites
let min1,max1,min2,max2;
for (let t of sprite1.tsub) {
for(let p of t){
let q = ap.dot(p);
min1 = Math.min(min1 ?? q,q);
max1 = Math.max(max1 ?? q,q);
}
}
for (let t of sprite2.tsub) {
for(let p of t){
let q = ap.dot(p);
min2 = Math.min(min2 ?? q,q);
max2 = Math.max(max2 ?? q,q);
}
}
if (!(max2 >= min1 && max1 >= min2))
return false;
}
}
}
return true;
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)