Я пытаюсь написать программу, которая обнаруживает столкновения между отрезками линии и шарами, и если столкновение происходит, то мяч отскакивает от линии
Используя учебники на этом сайте: 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и Частицы, чьи методы и действия понятны в коде. Я думаю, что проблема заключается в скорости шариков. Если частица еще не столкнулась с линией, возможно, что в следующем кадре она движется слишком сильно и пересекается слиния, поэтому расстояние между ее текущим положением и ближайшей точкой недостаточно велико. Для решения этой проблемы я должен либо изменить положение мяча, либо предсказать столкновение.Я не мог найти хороший путь к этим вещам, и, возможно, я ошибаюсь из-за прилипания. Также, когда вместо метода wallCollison
я использовал этот код:
p.velocity.setX(-(p.velocity.getX())); // Reversing the velocity
p.velocity.setY(-(p.velocity.getY()));
шары отскакивают, но, очевидно, внеправильный путь (но все же иногда некоторые шарики прилипают к линии), так что, вероятно, проблема со скоростью после столкновения!Как я могу это исправить?Спасибо за ваше внимание