Ошибка столкновения окружности, круги на орбите неподвижные круги - PullRequest
1 голос
/ 05 апреля 2011

У меня есть рабочий код для столкновения двух кругов, но теперь у меня есть специальные круги, которые не должны двигаться никогда. При попытке применить их к существующему коду движущиеся круги начинают вращаться вокруг статических, «закрепленных болтами» неподвижных кругов (когда я говорю орбиту, я имею в виду, что круг вращается вокруг круга, касаясь его некоторое время, пока не доберется до с другой стороны, а затем он продолжает свое первоначальное направление). Я пытался заставить часть кода работать для статических кругов (см. Огромный закомментированный раздел), но он работал только наполовину. Мои круги нормального размера в большинстве случаев работают нормально, но иногда они все еще вращаются. Кроме того, у меня есть еще один специальный круг, который не подвержен трению и имеет меньший размер, и этот круг почти всегда вращается. Кто-нибудь знает в чем моя проблема? Я наполовину понимаю, что здесь происходит с математикой, я получил ее из какой-то статьи о Гамасутре.

//move them apart so they don't intersect anymore
float distance = (float) Math.sqrt(((circleA.getCenterX() - circleB.getCenterX()) * (circleA.getCenterX() - circleB.getCenterX())) + ((circleA.getCenterY() - circleB.getCenterY()) * (circleA.getCenterY() - circleB.getCenterY())));
float separation = (circleA.getRadius() + circleB.getRadius()) - distance;

float xSepA = separation * (circleA.getCenterX() - circleB.getCenterX()) / distance / 2; //distance to move circleA in x dir
float ySepA = separation * (circleA.getCenterY() - circleB.getCenterY()) / distance / 2; //distance to move A in y dir
float xSepB = separation * (circleB.getCenterX() - circleA.getCenterX()) / distance / 2; //same for B
float ySepB = separation * (circleB.getCenterY() - circleA.getCenterY()) / distance / 2;

if (circleA.isStatic()) {
    xSepA = 0;
    ySepA = 0;
    xSepB = separation * (circleB.getCenterX() - circleA.getCenterX()) / distance; //same for B
    ySepB = separation * (circleB.getCenterY() - circleA.getCenterY()) / distance;
}
if (circleB.isStatic()) {
    xSepA = separation * (circleA.getCenterX() - circleB.getCenterX()) / distance;
    ySepA = separation * (circleA.getCenterY() - circleB.getCenterY()) / distance;
    xSepB = 0;
    ySepB = 0;
}

//moving them

circleA.setX(circleA.getX() + xSepA);
circleA.setY(circleA.getY() + ySepA);
circleB.setX(circleB.getX() + xSepB);
circleB.setY(circleB.getY() + ySepB);
//change velocity to bounce
Vector2f va = circleA.getVelocityVector();
Vector2f vb = circleB.getVelocityVector();
Vector2f vn = MathUtil.sub(circleA.getPositionVector(), circleB.getPositionVector());
vn.normalise();



float aa = va.dot(vn);
float ab = vb.dot(vn);

float optimizedPA = (2f * (aa - ab)) / (circleA.getMass() + circleB.getMass());
float optimizedPB = (2f * (ab - aa)) / (circleA.getMass() + circleB.getMass());

Vector2f newVA = MathUtil.sub(va, MathUtil.scale(vn, optimizedPA * circleB.getMass()));
Vector2f newVB = MathUtil.sub(vb, MathUtil.scale(vn, optimizedPB * circleA.getMass()));

//    if (circleA.isStatic()) {
//        optimizedPB = (2f * (ab - aa)) / (circleB.getMass());
//        newVA = va;
//        newVB = MathUtil.sub(vb, MathUtil.scale(vn, optimizedPB));
//        System.out.println(vb + " " + newVB);
//    } else if (circleB.isStatic()) {
//        optimizedPA = (2f * (aa - ab)) / (circleA.getMass() + circleB.getMass());
//        newVA = MathUtil.sub(va, MathUtil.scale(vn, optimizedPA));
//        newVB = vb;
//        System.out.println(va + " " + newVA);
//    }

circleA.setVX(newVA.getX());
circleA.setVY(newVA.getY());
circleB.setVX(newVB.getX());
circleB.setVY(newVB.getY());

1 Ответ

1 голос
/ 05 апреля 2011

Чтобы понять, как работает векторный подход, вы можете получить представление из этого статьи и примера . Одним из источников таких "орбитальных" аномалий является неправильная реализация изменчивых векторов; тщательные юнит-тесты необходимы. Нет простого способа отладки такого фрагмента кода; вам, вероятно, понадобится подготовить sscce .

...