Рисование звездных фигур с переменными параметрами - PullRequest
7 голосов
/ 26 апреля 2010

У меня есть задача написать программу, позволяющую пользователям рисовать звезды, которые могут различаться по размеру и количеству оружия. Когда я имел дело с основными звездами, я делал это с GeneralPath и таблицами очков:

     int xPoints[] = { 55, 67, 109, 73, 83, 55, 27, 37, 1, 43 };
     int yPoints[] = { 0, 36, 36, 54, 96, 72, 96, 54, 36, 36 };
     Graphics2D g2d = ( Graphics2D ) g;
     GeneralPath star = new GeneralPath();
     star.moveTo( xPoints[ 0 ], yPoints[ 0 ] );
     for ( int k = 1; k < xPoints.length; k++ )
     star.lineTo( xPoints[ k ], yPoints[ k ] );
     star.closePath();
     g2d.fill( star );

Какой метод выбрать для рисования звезд с переменным внутренним и внешним радиусом, а также с разным количеством рук? Вот что я должен получить:

альтернативный текст http://img228.imageshack.us/img228/6427/lab6c.jpg

Ответы [ 3 ]

20 голосов
/ 26 апреля 2010

Наличие n рук означает, что вы получите 2n вершин, четные на внешнем круге и нечетные на внутреннем круге. Если смотреть из центра, вершины находятся под равномерно расположенными углами (угол 2 * PI / 2 * n = Pi / n). На единичной окружности (r = 1) координаты x, y точек i = 0..n равны cos (x), sin (x). Умножьте эти координаты на соответствующий радиус (rOuter или rInner, в зависимости от того, является ли я нечетным или четным), и добавьте этот вектор к центру звезды, чтобы получить координаты для каждой вершины на пути звезды.

Вот функция для создания формы звезды с заданным количеством плеч, центральной координатой и внешним, внутренним радиусом:

public static Shape createStar(int arms, Point center, double rOuter, double rInner) {
    double angle = Math.PI / arms;

    GeneralPath path = new GeneralPath();

    for (int i = 0; i < 2 * arms; i++) {
        double r = (i & 1) == 0 ? rOuter : rInner;
        Point2D.Double p = new Point2D.Double(
            center.x + Math.cos(i * angle) * r, 
            center.y + Math.sin(i * angle) * r);
        if (i == 0) {
            path.moveTo(p.getX(), p.getY());
        }
        else {
            path.lineTo(p.getX(), p.getY());
        }
    }
    path.closePath();
    return path;
}
3 голосов
/ 26 апреля 2010

Я думаю, что вы должны использовать те же классы (GeneralPath), но здесь вы должны сосредоточиться на том, как вычислять координаты вершины.

Первое, что приходит мне в голову, это расположение 2N точек на окружности радиуса R1 с центром в (0,0). Затем "растянуть" каждую нечетную вершину, умножив ее вектор на c. Константа c должна быть равна R2 / R1 (то есть пропорция внутреннего и внешнего радиусов).

Но, может быть, есть более простое решение ...

2 голосов
/ 26 апреля 2010

Вот пример поиска одинаково расположенных точек на окружности , которые могут помочь. Просто сделайте количество точек, n , параметром в конструкторе.

private int n;
...
public CircleTest(int n) {
    ...
    this.n = n;
}
...
for (int i = 0; i < n; i++) {
    double t = 2 * Math.PI * i / n;
    ...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...