我正在尝试编写一个程序来检测线段和球之间的碰撞,如果发生碰撞,则球会弹起线
使用此站点中的教程: http://doswa.com/2009/07/13/circle-segment-intersectioncollision.html 我设法找到该直线上最接近的点。也是物理学 因为弹跳很简单,所以速度的法向矢量应该颠倒而切线矢量保持不变。我想我在这里写了很多东西,因为对于某些粒子和速度,它们弹跳完美,但是大多数情况下它们会粘在线!这是我需要解释的代码部分:
Particle p = Particles[i];
Vector v1 = new Vector(l.getP1());
Vector v2 = new Vector(l.getP2());
Vector c = new Vector(p.position.getX(), p.position.getY());
// a is the closet of points 1 & 2 to the circles center
// b is the farthest of points 1 & 2 to the circles center
float deltaD1 = c.subtract(v1).getMagnitude();
float deltaD2 = c.subtract(v2).getMagnitude();
Vector a;
Vector b;
if (deltaD1 <= deltaD2) {
a = v1;
b = v2;
} else {
a = v2;
b = v1;
}
float r = p.getRadius();
// seg_v is a vector from a to b
// pt_v is a vector from a to the center of the circle
Vector seg_v = (b.subtract(a)).normalize();
Vector pt_v = c.subtract(a);
// now we find the closest point on the line to the circle
float closeSize = pt_v.dot(seg_v);
Vector closest;
float distance;
if (closeSize <= 0) {
closest = a;
distance = pt_v.getMagnitude();
} else {
closest = seg_v.multiply(closeSize).add(a);
distance = c.getDistance(closest);
}
// now the collision checking!
if (distance <= r) {
// repositioning the particle
Vector tangent = seg_v;
// the normal vector is perpendicular to the line and it is a unit vector so we
// have to normalize it
Vector normal = new Vector(-seg_v.getX(), seg_v.getY());
normal = normal.normalize();
wallCollision(p, tangent, normal); }}}
private void wallCollision(Particle p, Vector tangent, Vector normal) {
// when collision happens the normal vector changes but the tangent vector is
// the same
float vt = p.getVelocity().dot(tangent);
float vn = -p.getVelocity().dot(normal);
Vector newVelocity = tangent.multiply(vt).add(normal.multiply(vn));
p.setVelocity(newVelocity);
}
//游戏循环:
public void mainLoop() {
long previousTime = System.currentTimeMillis();
long currentTime = previousTime;
long elapsedTime;
long totalElapsedTime = 0;
int frameCount = 0;
while (true) {
currentTime = System.currentTimeMillis();
elapsedTime = (currentTime - previousTime); // elapsed time in seconds
totalElapsedTime += elapsedTime;
// we are checking if more than one second has passed
if (totalElapsedTime > 1000) {
this.fps = frameCount;
frameCount = 0;
totalElapsedTime = 0;
}
moveParticles(elapsedTime / 1000f);
render();
try {
Thread.sleep(5);
} catch (Exception e) {
e.printStackTrace();
}
previousTime = currentTime;
frameCount++;
}
}
我知道代码很乱!我创建了一个名为Vector和Particles的类,该类的方法和动作在代码中清晰可见。我认为问题在于球的速度。如果粒子尚未与直线碰撞,在下一帧中它可能会移动太多并与直线相交,因此其当前位置与最近点之间的距离不够大。要解决此问题,我要么必须重新定位球,要么预测碰撞。我找不到解决这些问题的好方法,也许我对粘贴是错误的。此外,我使用以下代码代替wallCollison
方法:
p.velocity.setX(-(p.velocity.getX())); // Reversing the velocity
p.velocity.setY(-(p.velocity.getY()));
球反弹但明显以错误的方式反弹(但仍然偶尔有一些球粘在直线上),因此问题可能出在碰撞后的速度上! 我该如何解决? 感谢您的关注