我正在执行的部分任务需要根据给定的行和列在两个点之间画一条线。我的问题是,对于3x3的正方形,它会完美地绘制第0列第0行的线条。但是,当我创建5x5的正方形时,它的位置错误。

在下面显示的两个示例中,线条均绘制在第0列第0列。请注意,图像相对较大,因此最好不要将其嵌入。

5x5 Example

3x3 Example

我正在使用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行将显示如下。

Row 2, Column 0 Example

最佳答案

这个问题与魔术数字有关


我会同意的。但这也从静态变量的错误值开始。

1)“分隔”定义不正确。绘制椭圆形时,可以将X / y值增加SEPARATION。但是,由于椭圆的直径为25,因此两个椭圆之间的实际间距仅为175。因此,我建议“分隔”应该仅为175。

2)宽度/高度然后也使用随机数。在我看来,您想要在所有椭圆形之前/之后都留出空间。因此,宽度/高度应类似于:

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


这将允许在每个椭圆形之前/之后以及每个球的绘画之前有相等的空间。

3)现在,您的XSTART / YSTART值就是SEPARATION值(175)。

4)现在,当您绘制每个椭圆形时,您需要通过DIAMETER + SEPARATION增加下一个位置。

5)当您绘制矩形时,宽度将始终是恒定的。那就是直径+分离

6)高度也将取决于您想要线条的粗细

7)因此剩下的就是如何计算x / y位置。对于第一行/列,您知道“ x”将只是分隔符。对于下一列,您将按DIAMETER和SEPARATION递增。因此,一般公式如下所示:

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


“ y”计算将类似,除了在计算中使用“行”值。

8)最后,您可能需要调整“ x”值,以便从一个椭圆的中心到另一椭圆的中心进行绘制,因此您只需加上DI​​AMTER /2。对于“ y”值,调整会有所不同像(直径-行高)/ 2。

没有任何建议得到检验,但是我希望您能想到,您真正需要知道的仅有两个数字是DIAMETER和SEPARATION。

注意,如果要定义您的类,则不会使用静态变量。我将传递“球”和“分离”作为参数。然后在构造函数中,我将计算其他值。

09-11 04:46