java 2d столкновение с не вертикальными или горизонтальными линиями - PullRequest
0 голосов
/ 22 июля 2011

Я делаю игру и застрял с обнаружением столкновения не с вертикальной или горизонтальной линией с мячом. У меня есть класс для обнаружения столкновения с шарика на шар мой источник:

private boolean calcCollision(balls i, balls j) {
    double x, y, d2;

    // displacement from i to j
    y = (j.y - i.y);
    x = (j.x - i.x);

    // distance squared
    d2 = x * x + y * y;

    // dividing by 0 is bad
    if (d2 == 0.)
        return false;

    // if d^2 < (25)^2, the ballss have collided
    if (d2 < 625.) {
        double kii, kji, kij, kjj;

        kji = (x * i.dx + y * i.dy) / d2; // k of j due to i
        kii = (x * i.dy - y * i.dx) / d2; // k of i due to i
        kij = (x * j.dx + y * j.dy) / d2; // k of i due to j
        kjj = (x * j.dy - y * j.dx) / d2; // k of j due to j

        // set velocity of i
        i.dy = kij * y + kii * x;
        i.dx = kij * x - kii * y;

        // set velocity of j
        j.dy = kji * y + kjj * x;
        j.dx = kji * x - kjj * y;

        return true;
    }

    return false;
}

private void calcFriction(balls d) {
    double k = (d.dx * d.dx + d.dy * d.dy);
    k = Math.sqrt(k) * 26;

    // dividng by zero is bad
    if (k == 0)
        return;

    // set ddx and ddy
    d.ddy = -d.dy / k;
    d.ddx = -d.dx / k;
}
private void fixOverlap(balls i, balls j) {
    double x, y, k;

    // the real displacement from i to j
    y = (j.y - i.y);
    x = (j.x - i.x);

    // the ratio between what it should be and what it really is
    k = 25.1 / Math.sqrt(x * x + y * y);

    // difference between x and y component of the two vectors
    y *= (k - 1) / 2.;
    x *= (k - 1) / 2;

    // set new coordinates of ballss
    j.y += y;
    j.x += x;
    i.y -= y;
    i.x -= x;
}

private void doFriction(balls d) {
    d.dy += d.ddy;
    d.dx += d.ddx;

    // if dx and ddx now have the same sign then stop
    if (d.dx > 0 == d.ddx > 0) {
        d.dx = 0;
        checkReady(); // check ready after stopping
    } if (d.dy > 0 == d.ddy > 0) {
        d.dy = 0;
        checkReady();
    }

}

private void checkBounds(balls d) {
    // hit top or bottom
    if (d.y > board.getHeight() - ballRadius) {
        d.dy = -Math.abs(d.dy);
        d.ddy = Math.abs(d.ddy);
    } else if (d.y < 0.) {
        d.dy = Math.abs(d.dy);
        d.ddy = -Math.abs(d.ddy);
    }

    // hit left or right side
    if (d.x > board.getWidth() - ballRadius) {
        d.dx = -Math.abs(d.dx);
        d.ddx = Math.abs(d.ddx);
    } else if (d.x < 0.) {
        d.dx = Math.abs(d.dx);
        d.ddx = -Math.abs(d.ddx);
    }
}

private void calcPositions() {
    try {
        int a, b;
        balls i, j;
        for (a = 0; a < balls.size(); a++) {
                i = balls.elementAt(a);

                // check if balls is moving
                if (i.dy != 0 || i.dx != 0) {
                    // move balls
                    i.y += i.dy;
                    i.x += i.dx;

                    if (friction)
                        doFriction(i);
                }

                // check fall off the board
                checkBounds(i);

                // check if balls has collided with any balls after it
                for (b = a + 1; b < balls.size(); b++) {
                    j = balls.elementAt(b);
                    // if they collided
                    if (calcCollision(i, j)) {
                        // fix possible overlapping
                        if (overlap)
                            fixOverlap(i, j);

                        // calc new friction of ballss i and j
                        calcFriction(i);
                        calcFriction(j);
                       }
                }

        }
    } catch (Exception ex) {
        System.out.println(ex.getMessage());
    }
}

Может быть, кто-то может помочь

1 Ответ

0 голосов
/ 23 июля 2011

Объекты столкновений, которые имеют только прямые и горизонтальные линии (или более общие: линии, которые параллельны осям системы координат), называются ограничивающими прямоугольниками с осями.

Наиболее широко используемый алгоритм для столкновения 2DОбнаружение с использованием не AABB основано на «Теореме о разделяющей оси».

Вот отличное руководство для него:

http://www.codezealot.org/archives/55

...