Столкновение Ответ метод - PullRequest
       9

Столкновение Ответ метод

0 голосов
/ 07 сентября 2011

Привет, я пытаюсь реализовать простой алгоритм обнаружения столкновений сфер, как описано здесь: http://wp.freya.no/3d-math-and-physics/simple-sphere-sphere-collision-detection-and-collision-response/

Поэтому я реализую метод, чтобы проверить, происходит ли столкновение:

private boolean advancedSphereSphere(Sphere a, Sphere b) {

Vector2D s = a.getPos().sub(b.getPos());
Vector2D v = a.getVelocity().sub(b.getVelocity());

float r = a.getRadius() + b.getRadius();

double c1 = s.dot(s) - r*r;

if(c1 < 0.0) {
    timeToCollision = .0f;
    return true;
}

double a1 = v.dot(v);
if(a1 < 0.00001f) {
    return false;
}

double b1 = v.dot(s);
if(b1 >= 0.0) {
    return false;
}

double d1 = b1*b1 - a1*c1;
if(d1 < 0.0) {
    return false;
}

timeToCollision = (float) (-b1 - Math.sqrt(d1) / a1);

return true;
}

Затем у меня есть метод onDraw, который зацикливается на рисовании всех необходимых элементов, например:

protected void onDraw(Canvas canvas) {
    flowPhysics(false);
    for(Sphere s : mSpheres) {
        s.draw(canvas);
    }

    invalidate();
}

, и проблема возникает в методе flowPhysics (логический), в этой строке:

for(int i=0; i < mSpheres.size(); ++i) {
            for(int j=i+1; j < mSpheres.size(); ++j) {

                Sphere a = mSpheres.get(i);
                Sphere b = mSpheres.get(j);

                if(advancedSphereSphere(a, b) || step) {
                    if(timeToCollision < dt && !step) {
                        flowPhysics(true);
                    }

                    if(step) {
                        sphereCollisionResponse(a, b);
                    }
                }

            }
        }

Когда вызывается advancedSphereSphere (), первая Сфера исчезает, я проверил и заметил, что проблема в том методе в первой строке:

Vector2D s = a.getPos().sub(b.getPos());

, если я добавлю сюда что-то еще и не вычтуb из векторов, он рисует шары (но столкновения не происходит).Приведенный выше код Java в основном портирован здесь: http://wp.freya.no/websvn/filedetails.php?repname=Public&path=%2Fopengl%2Fcollisiondetect%2Fcollisiondetect.cpp

Можете ли вы дать мне представление о том, в чем проблема?

Спасибо

ОБНОВЛЕНИЕ

private void sphereCollisionResponse(Sphere a, Sphere b)
    {
        double m1, m2, x1, x2;
        Vector2D v1, v2, v1x, v2x, v1y, v2y;
        Vector2D x = new Vector2D(a.getPos().sub(b.getPos()));

        x.normalize();
        v1 = new Vector2D(a.getVelocity());
        x1 = x.dot(v1);
        v1x = new Vector2D(x.multiply(x1));
        v1y = new Vector2D(v1.sub(v1x));
        m1 = a.getMass();

        x = new Vector2D(x.multiply(-1));
        v2 = new Vector2D(b.getVelocity());
        x2 = x.dot(v2);
        v2x = new Vector2D(x.multiply(x2));
        v2y = new Vector2D(v2.sub(v2x));
        m2 = b.getMass();

        Vector2D nn = new Vector2D(v1x.multiply(m1-m2));
        Vector2D mm = new Vector2D(nn.divide(m1+m2));
        Vector2D tt = new Vector2D(v2x.multiply(2*m2));
        Vector2D rr = new Vector2D(tt.divide(m1+m2));
        Vector2D gg = new Vector2D(mm.add(rr));
        Vector2D ss = new Vector2D(gg.add(v1y));

        Vector2D nva = ss; 
        a.setVelocity(nva);

        Vector2D nvb = new Vector2D(v1x.multiply(2*m1).divide(m1+m2).add(v2x.multiply(m2-m2).divide(m1+m2).add(v2y)));
        b.setVelocity(nvb);     
} 

1 Ответ

0 голосов
/ 07 сентября 2011

Если проблема действительно в этой строке

Vector2D s = a.getPos().sub(b.getPos());

тогда я подозреваю, что проблема может быть в вашем Vector2D классе. Вы должны проверить, что метод sub просто возвращает новый Vector2D и не изменяет координаты исходного вектора a. Сохранение ваших объектов неизменными, насколько это возможно, делает их более безопасными для использования.

В противном случае ответом будет модульное тестирование . Научиться использовать JUnit или TestNG окупится в долгосрочной перспективе, но на данный момент вам могут помочь даже несколько специальных заявлений о печати. Вы должны быть в состоянии проверить правильность математики независимо от того, как сферы появляются на вашем экране, и последовательное выполнение этого, вероятно, приведет вас к более четкому дизайну.

Просто проверяя, что положение каждой сферы остается неизменным после столкновения, и что скорости соответствуют ожидаемым в нескольких простых случаях, вы, скорее всего, обнаружите ошибку в своем коде. Например, если обе скорости равны нулю заранее, то впоследствии они должны быть равны нулю. Если столкновение является упругим и одна сфера (A) сталкивается в лоб с другой неподвижной сферой (B), сфера A должна быть стационарной после этого, а сфера B должна иметь скорость, с которой начиналась A.

Я не проверял математику в вашем коде на http://pastie.org/2499691, но когда я установил несколько простых классов, чтобы заполнить зависимости и дать ему некоторые разумные начальные условия, он не сохраняет импульс, поэтому я может полагать, что при некоторых значениях шары могут в конечном итоге вылететь за пределы экрана со скоростью света.

Если у вас есть право на физику, вы можете работать над любыми оставшимися проблемами с отображением сфер в безопасности, зная, что проблема действительно должна лежать там.

...