1
votes

I have working code below for collision of two circles, but now I have special circles that aren't supposed to move ever. When trying to apply them with the existing code, moving circles start to orbit around the static, "bolted", unmoving circles (when I say orbit, i mean the circle revolves around the circle while touching it for a while until it gets to the other side, and then it continues on it's original direction). I tried to make a part of the code work for the static circles(see huge commented out section), but it only half worked. My normal sized circles work fine, most of the time, but sometimes it does still orbit. Also, i have another special circle that isn't affected by friction and is smaller and that one almost always orbits. Does anyone know what my problem is? I half understand the math going on here, I got it from some gamasutra article.

//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
Reformatted code; please revert if incorrect. - trashgod
@trashgod: You changed the code or you just made it nicer to look at? - Rahat Ahmed
Just the indentation, I believe. - trashgod

1 Answers

1
votes

To understand how the vector approach works, you may get some insight from this article and example. One source of such "orbit" anomalies is an incorrect implementation of mutable vectors; thorough unit tests are essential. There's no easy way to debug a fragment of code like this; you'll probably need to prepare an sscce.