Нарисуйте линию на основе строки и столбца - PullRequest
1 голос
/ 19 мая 2019

Часть задачи, которую я выполняю, требует, чтобы я провел линию между двумя точками на основе заданной строки и столбца.Моя проблема в том, что для квадрата 3x3 он отлично проведет линию для столбца 0, строки 0. Однако, когда я создаю квадрат 5x5, он находится в неправильном положении.

В обоих примерах, показанных ниже, линия рисуется в столбце 0, строке 0. Обратите внимание, что изображения относительно большие, поэтому, вероятно, было бы лучше не встраивать их.

*Пример 1005 * 5x5

3x3 Пример

Я использую Swing, а сигнатура метода drawRectangle - (x1, y1, x2, y2).В этом случае 'r' представляет строку, а 'c' представляет значение столбца, указанное в аргументах.

    import java.awt.*;
    import javax.swing.*;

    public class SwingMain extends JPanel {

       final static int SEPARATION = 200;
       final static int DIAMETER   = 25;
       final static int NBALLS     = 4;
       final static int WIDTH      = NBALLS * 250;
       final static int HEIGHT     = NBALLS * 250;
       final static int XSTART     = WIDTH / (NBALLS + 2);
       final static int YSTART     = HEIGHT / (NBALLS + 2);
       JFrame           frame      = new JFrame();

       public static void main(String[] args) {
          SwingUtilities.invokeLater(() -> new SwingMain().start());
       }

       public void start() {
          frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          setPreferredSize(new Dimension(WIDTH, HEIGHT));
          frame.add(this);
          setBackground(Color.BLACK);
          frame.pack();
          frame.setLocationRelativeTo(null);
          frame.setVisible(true);
       }

       @Override
       public void paintComponent(Graphics g) {
          super.paintComponent(g);
          Graphics2D g2d = (Graphics2D) g;

          g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
          g2d.setColor(Color.white);

          int y = YSTART;
          for (int r = 0; r < NBALLS; r++) {
             int x = XSTART;
             for (int c = 0; c < NBALLS; c++) {
                g2d.fillOval(x, y, DIAMETER, DIAMETER);
                x += SEPARATION;
             }
             y += SEPARATION;
          }

          drawHorizontalLine(g2d, 0, 0);

       }

       public void drawHorizontalLine(Graphics2D g, int r, int c) {
           drawRectangle(g, 175 * (c + 1), 155 * (r + 1), 375 * (c + 1), 175 * (r + 1), Color.WHITE);
       }

       public void drawRectangle(Graphics2D graphic, int x1, int y1, int x2, int y2, Color c) {
           graphic.fillRect(Math.min(x1, x2), Math.min(y1, y2), Math.abs(x1 - x2), Math.abs(y1 - y2));
        }

    }

Я считаю, что проблема связана с магическими числами, которые я вставил дляDrawRectangle.Скорее, я должен также включить ширину и высоту окна.Но я просто полностью потерялся.Ширина окна основана на (n * 250), где n обозначает количество точек.Так, в примере 5x5 n = 6, тогда как в 3x3 - n = 4. Кроме того, если кто-то может подсказать, как добавить отступы во внешнюю область кругов, которая является четной.В настоящее время моя формула ширины и высоты окна довольно ужасна.

Кроме того, довольно бессмысленная формула работает только для столбца 0, строки 0. Поэтому, если я попытаюсь нарисовать линию в столбце 0, строка 2 будетпоказано ниже.

Строка 2, столбец 0 Пример

1 Ответ

1 голос
/ 19 мая 2019

проблема связана с магическими числами

Я бы согласился. Но это также начинается с неправильных значений для ваших статических переменных.

1) «РАЗДЕЛЕНИЕ» определено неправильно. Когда вы рисуете овалы, вы увеличиваете значения x / y на SEPARATION. Но поскольку овал имеет диаметр 25, фактическое расстояние между двумя овалами составляет всего 175. Поэтому я бы предложил разделение только 175.

2) WIDTH / HEIGHT также использует случайные числа. Мне кажется, ты хочешь места до / после всех овалов. Таким образом, ширина / высота должна быть что-то вроде:

a) number of ovals * diameter, plus
b) (number of ovals + 1) * separation. 

Это даст равное пространство перед / после каждого овала, а также окраску каждого шара.

3) Теперь ваши значения XSTART / YSTART - это просто значение SEPARATION (175).

4) Теперь, когда вы рисуете каждый овал, вам нужно увеличить следующую позицию ДИАМЕТРОМ + РАЗДЕЛЕНИЕ.

5) Когда вы рисуете прямоугольник, ширина всегда будет постоянной. Это ДИАМЕТР + РАЗДЕЛЕНИЕ

6) Высота также будет постоянной в зависимости от толщины линии

7) Итак, все, что остается, - это как рассчитать местоположение х / у. Для первой строки / столбца вы знаете, что «х» будет просто РАЗДЕЛЕНИЕ. Для следующего столбца вы увеличиваете на ДИАМЕТР и РАЗДЕЛЕНИЕ. Таким образом, общая формула будет выглядеть примерно так:

a) SEPARATION, plus
b) (column * (DIAMETER + SEPARTION))

Расчет "y" будет аналогичным, за исключением того, что при вычислении будет использоваться значение "row".

8) наконец, вы, вероятно, захотите отрегулировать значение "x", чтобы рисовать от центра одного овала до цента другого, поэтому вы просто добавите DIAMTER / 2. Для значения "y" корректировка будет что-то вроде (ДИАМЕТР - высота строки) / 2.

Ни одно из предложений не было проверено, но я надеюсь, что вы поймете, что только два числа, которые вам действительно нужно знать, это ДИАМЕТР и РАЗДЕЛЕНИЕ.

Обратите внимание, если бы я определял ваш класс, я бы не использовал статические переменные. Я бы передавал «шары» и «разделение» в качестве параметров. Тогда в конструкторе я бы вычислил другие значения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...