Как определить перекрывающиеся круги и соответственно заполнить цвет?

Я создал 5 кругов со случайными координатами x и y и радиусами, используя 3 массива (для размера x, y и радиуса). Однако мне нужно, чтобы круги динамически меняли цвет в зависимости от того, перекрываются ли они с другим кругом. Поэтому, если один из 5 кругов вообще не перекрывается, он должен быть окрашен в черный цвет. Перекрывающиеся круги должны быть голубыми. Два круга считаются перекрывающимися, если расстояние между их центральными точками меньше суммы их радиусов.

Это то, что я написал до сих пор для класса кругов. Следующий код успешно нарисует 5 кругов в окне апплета, и расстояния будут успешно рассчитаны, но проблема связана с раскраской. Кажется, в заливке цвета есть логическая ошибка, и я не вижу здесь проблемы. Какие-либо предложения? Большое спасибо.

public class Circles extends Applet {

public void paint(Graphics page)
{
    Random locator = new Random();
    int [] xpt = new int [5];
    int [] ypt = new int [5];
    int [] rad = new int [5];

    setPreferredSize (new Dimension(300, 300));
    for (int i = 0; i < xpt.length; i++){

        xpt[i] = locator.nextInt(100); //need to set a number or it goes into millions, cannot set it in Random()
        ypt[i] = locator.nextInt(100);
        rad[i] = locator.nextInt(100);
        System.out.println("The #" + i +  " x-point: " + xpt[i] + " y-point: " + ypt[i] + " radius: " + rad[i]);  //for debugging purposes

        for (int j = 0; j < xpt.length; j++){
            double xpoint1 = xpt[i]+rad[i];
            double ypoint1 = ypt[i]+rad[i];
            double xpoint2 = xpt[j]+rad[j];
            double ypoint2 = ypt[j]+rad[j];
            double radius1 = rad[i];
            double radius2 = rad[j];
            double theDistance = distance(xpoint1,ypoint1,xpoint2,ypoint2); 
            System.out.println("Comparing " + i + " to " + j); //for debugging and logic checking
            if (i==j)
                ;
            else if (theDistance <= (radius1+radius2))
            {
                page.setColor(Color.cyan);
                page.fillOval(xpt[i], ypt[i], rad[i], rad[i]);
                //page.fillOval(xpt[j], ypt[j], rad[j], rad[j]);
                System.out.println("Overlap occurred. Colored " + i + " and " + j + " cyan.");
                System.out.println("Center points: ("+ xpoint1 +", "+ ypoint1 +") and ("+ xpoint2 + ", "+ ypoint2 + ").");
            }
            else  
            {
                page.setColor(Color.black);
                page.fillOval(xpt[i], ypt[i], rad[i], rad[i]);
                //page.fillOval(xpt[j], ypt[j], rad[j], rad[j]);
                System.out.println("No overlap. Made " + i + " and " + j + " black.");
            }
        }
    }
}

public static double distance(
        double x1, double y1, double x2, double y2) {
    return Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));

}
}

person sxflynn    schedule 13.11.2010    source источник


Ответы (2)


Линии xpoint, ypoint и т. д. делают не то, что вы думаете.

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

So:

function circlesCollide(x1, y1, r1, x2, y2, r2){
    return (distance(x1, y1, x2, y2) <= (r1 + r2));
}
person Zack Bloom    schedule 13.11.2010
comment
Я думаю, что делаю это здесь - иначе если (theDistance ‹= (radius1+radius2)) - person sxflynn; 13.11.2010
comment
Строки xpoint, ... искажают ваши данные, моя функция — это все, что вам нужно сделать. - person Zack Bloom; 13.11.2010

Почему ты +rad[] здесь? Вам не нужно добавлять радиус для сравнения расстояния.

        double xpoint1 = xpt[i]+rad[i];
        double ypoint1 = ypt[i]+rad[i];
        double xpoint2 = xpt[j]+rad[j];
        double ypoint2 = ypt[j]+rad[j];
 [...]
        double theDistance = distance(xpoint1,ypoint1,xpoint2,ypoint2); 
 [...]
        page.fillOval(xpt[i], ypt[i], rad[i], rad[i]);

Вы должны использовать xpt / ypt для расстояния. не xpoint1, и используйте - для значения и 2 * радиус для размера ...... т.е.:

        double xpoint1 = xpt[i]-rad[i];
        double ypoint1 = ypt[i]-rad[i];
        double xpoint2 = xpt[j]-rad[j];
        double ypoint2 = ypt[j]-rad[j];
 [...]
        double theDistance = distance(xpt[i],ypt[i],xpt[j],ypt[j]); 
 [...]
        page.fillOval(xpoint1 , ypoint1, 2*rad[i], 2*rad[i]);
person J-16 SDiZ    schedule 13.11.2010
comment
Но когда вы используете '''page.fillOval(xpt[i], ypt[i], rad[i], rad[i]);''', он рисует из левого верхнего угла угла, поэтому мне пришлось добавьте длину радиуса к координатам x и y, чтобы найти центр нарисованного круга - person sxflynn; 13.11.2010
comment
Нет, вы меня неправильно понимаете. Я обновил ответ кодом, чтобы уточнить. - person J-16 SDiZ; 13.11.2010