问题描述
我正在学习 SAT(分离轴定理)算法和碰撞响应,在我应用旋转之前它似乎工作正常。 如果两个碰撞形状都在旋转,它们会粘在一起并且无法解决碰撞,我猜这是由于形状旋转回对撞机。
我在碰撞检查之前一次旋转所有形状(发生在 render
方法中),但我尝试在渲染后旋转以及在渲染循环本身中旋转,这两种方法都不起作用.
sprites[0].rotate(1);
sprites[2].rotate(2);
sprites[3].rotate(5);
for (let sprite of sprites) {
// render loop
sprite.render(ctx);
}
没有响应,实际检测工作正常(尝试用 if (this.colliding_SAT(sprite)) {
替换第 59 行),所以我怀疑这是检测的问题,而是响应的问题。
我将如何解决这个问题,以便正确解决碰撞问题,或者 SAT 仅适用于静态形状?
// SAT colliding algorithm with response
let sprite1 = this;
let sprite2 = cand;
let overlap; // min dist to resolve collision
for (let sprite = 0; sprite < 2; sprite++) {
if (sprite == 1) {
// flip to avoid repetitive code
sprite1 = cand;
sprite2 = this;
}
for (let a = 0; a < sprite1.vertices.length; a++) {
const b = (a + 1) % sprite1.vertices.length;
// normal to sprite edge (axis projection)
const ap = new Vector(-(sprite1.vertices[b].y - sprite1.vertices[a].y),sprite1.vertices[b].x - sprite1.vertices[a].x);
//stablize slightly
ap.norm();
// find min max for both sprites
let min1,max1,min2,max2;
for (let p of sprite1.vertices) {
let q = ap.dot(p);
min1 = Math.min(min1 ?? q,q);
max1 = Math.max(max1 ?? q,q);
}
for (let p of sprite2.vertices) {
let q = ap.dot(p);
min2 = Math.min(min2 ?? q,q);
max2 = Math.max(max2 ?? q,q);
}
let op = Math.min(max1,max2) - Math.max(min1,min2);
overlap = Math.min(op,overlap ?? op);
if (!(max2 >= min1 && max1 >= min2))
return false;
}
}
// sprites are colliding
const d = new Vector(sprite2.pos.x - sprite1.pos.x,sprite2.pos.y - sprite1.pos.y);
d.norm();
sprite1.translate(overlap * d.x,overlap * d.y);
return false;
见附件 jsfiddle:https://jsfiddle.net/sbnjxag8/
解决方法
原来我需要将位置(pos
属性)应用到每个精灵,并且由于以下行,不能将其保留为默认 0,0:const d = new Vector(sprite2.pos.x - sprite1.pos.x,sprite2.pos.y - sprite1.pos.y);
sprites.push(new Sprite({
vertices: [
new Vector(300,250),new Vector(320,270),new Vector(300,270)
],pos: new Vector(310,260)
}));