Как я могу проверить, равны ли значения в одном массиве, не проверяя одно и то же - PullRequest
0 голосов
/ 15 января 2019

У меня есть этот массив

Ball[] balls = new Ball[7]; // 7 just being an example

В моем классе Ball у меня есть геттеры и сеттеры для значений x и y. Я пытаюсь сравнить значения x и y, чтобы убедиться, что они не пересекаются.

Моей первой мыслью было сделать петлю, похожую на

for(Ball b1 : balls) {
    for(Ball b2 : balls) {
    if(b1.intersects(b1, b2)) {. . .} // I made intersects, not my issue 
    }
}

Но это нехорошо, поскольку сравнивает:

  1. шары от 0 до шары 0
  2. шары 1 к шарам 1
  3. и т.д.

    for(int i = 0; i < balls.length; i++) {
        System.out.println(f.getContentPane().getWidth() + "\n" + f.getContentPane().getHeight());
    
        int radius = 10 + rand.nextInt(20);
    
        balls[i] = new Ball(360, radius,
                rand.nextInt(f.getContentPane().getWidth() - 4 * radius - 5) + radius + 5,
                rand.nextInt(f.getContentPane().getHeight() - 4 * radius - 5) + radius + 5
        );
    }
    for(Ball b1 : balls) {
        for (Ball b2 : balls) {
            while (b1.intersects(b1, b2)) {
                System.out.println("Ball started out inside of another, replacing now.");
                b1.setX(rand.nextInt(f.getContentPane().getWidth() - 2 * b1.getRadius() - 5) + b1.getRadius() + 5);
                b1.setY(rand.nextInt(f.getContentPane().getHeight() - 2 * b1.getRadius() - 5) + b1.getRadius() + 5);
            }
        }
    }
    

////////////// смена классов //////////////////

class Ball {
private int direction;
private int radius;
private int x,y;

Ball(int direction, int radius, int x, int y) {
    this.direction = direction;
    this.radius = radius;
    this.x = x;
    this.y = y;
}

// Getters + Setters here

boolean intersects(Ball b1, Ball b2) {
    double x = Math.pow((b2.getX() - b1.getX()), 2);    // Distance formula
    double y = Math.pow((b2.getY() - b1.getY()), 2);    // Distance formula
    double r = b1.getRadius() + b2.getRadius();

    //System.out.println(x + " + " + y + " <= " + r );
    return x + y <= r;
}

}

(Не обращайте внимания на то, что я не поместил свой первый кусок кода в метод и класс, я сделал это в моем реальном коде.)

Я, по какой-то причине, не могу придумать способ сделать это без большого количества операторов if

(поэтому я прошу лучший способ сделать это)

1 Ответ

0 голосов
/ 15 января 2019

Один из способов сравнения каждой отдельной пары (т.е. без шарика с самим собой) из Ball s, без сравнения какой-либо пары более одного раза, будет:

for (int i = 0; i < balls.length; ++i) {
    Ball b1 = balls[i];
    for (int j = i+1; j < balls.length; ++j) {
        Ball b2 = balls[j];
        if (b1.intersects(b1, b2)) {
            // ...
        }
    }
}

Обнаружение новых столкновений, возникших в процессе разрешения предыдущих, означает просто сделать несколько проходов через balls до тех пор, пока у вас больше не будет столкновений. Простой, возможно, наивный способ сделать это будет примерно так:

boolean foundCollision;
int numTries = 0;
int maxTries = 1000000;
do {
    foundCollision = false;
    for (int i = 0; i < balls.length; ++i) {
        Ball b1 = balls[i];
        for (int j = i+1; j < balls.length; ++j) {
           Ball b2 = balls[j];
           if (b1.intersects(b1, b2)) {
               foundCollision = true;
               // resolve collision...
        }
    }
    ++numTries;
} while (foundCollision && numTries < maxTries);
if (numTries >= maxTries)
    System.err.println("Couldn't sort out balls after " + maxTries + "tries: what now?");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...