2016-06-09 64 views
0

假设我有给定的数组:绘制图形为Array

int[] array = { 
     0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0 
    }; 

会不会有一种方法来绘制图形成数组?例如,假设我们有一种方法可以通过x和y坐标来访问数组中的数据,那么我们可以制作一个方法,该方法会根据2个坐标放置一个穿过此数组的线。该守则将是这个样子:

public void drawLine(int x1, int y1, int x2, int y2) { 
    ...  
} 

,并会传递这样的事情:

int[] array = { 
     0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0 
    }; 

进入这个:

int[] array = { 
     1, 0, 0, 0, 0, 
     0, 1, 0, 0, 0, 
     0, 0, 1, 0, 0, 
     0, 0, 0, 1, 0, 
     0, 0, 0, 0, 1 
    }; 

你必须要能够在任何一组通的坐标并通过阵列放置一条计算出的线。我将如何实现这一点?

调用的drawLine(1,0,3,4)将创建类似:

int[] array = { 
    0, 1, 0, 0, 0, 
    0, 0, 1, 0, 0, 
    0, 0, 1, 0, 0, 
    0, 0, 0, 1, 0, 
    0, 0, 0, 1, 0 
}; 

此外,如果你到它是存在的,我可以指定任意数量的点,并把它们都连接方式然后填写? (不,我不想使用任何库)。

+1

[Bresenham's line algorithm](https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm)对于绘制线条很有用。 – MikeCAT

+0

'drawiLine(1,0,2,4)'的输入怎么样?至少对我而言,没有通用的解决方案,因为不清楚“任何一组坐标”的结果如何。 – SomeJavaGuy

+1

'y'坐标在一维数组中没有意义。 – Berger

回答

2

非常不好的方法来做到这一点(而不是自己实现绘图逻辑)将使用BufferedImage与您的数组的维度和绘制。绘制完想要的线后,您将遍历BufferedImage的像素并检查绘制了哪些像素。

private static void drawToArray(int[][] array2d, int x1, int y1, int x2, int y2) { 
    int width = array2d[0].length; // width is columns and columns are second 
    int height = array2d.length; // height is rows and rows are first 

    BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); 
    Graphics2D g2d = image.createGraphics(); 
    g2d.setBackground(Color.WHITE); 
    g2d.fillRect(0, 0, width, height); // paint background white 
    g2d.setColor(Color.BLACK); 
    BasicStroke bs = new BasicStroke(1); // set black brush to size 1 (1 pixel) 
    g2d.setStroke(bs); 

    g2d.drawLine(x1, y1, x2, y2); // paint line on image 

    // fill array with values, check entire image 
    for (int row = 0; row < height; row++) { 
     for (int column = 0; column < width; column++) { 
      int clr = image.getRGB(row,column); // get color of pixel at position 
      if (clr == Color.WHITE.getRGB()) { // white is -1 
       array2d[row][column] = 0; 
      } else { 
       array2d[row][column] = 1; 
      } 
     } 
    } 
    g2d.dispose(); 
    // returning array is not necesery I am editing the array2d variable passed in 
} 

用法

int[][] arr = new int[5][5]; 
drawToArray(arr, 0, 0, 2, 5); 

这个例子假设你的阵列是二维的,并且每行是相同的长度。如果你想使用一维数组,你将不得不自己定义宽度和高度。也代替

array2d[row][column] = 0; 

你会

array1d[row*width + column] = 0; 

编辑1:编辑我的回答是更普遍的

编辑2:考虑性能

我怀疑我能提高因此drawLine方法仅用于改进就是将其转换为2d数组。可以从Image中获取表示为整数值的像素数组,并将其转换为2d数组。我更新了绘制ToArray方法,并将注释掉的行作为解释。

private static void drawToArray(int[][] array2d, int x1, int y1, int x2, int y2) { 
    int width = array2d[0].length; // width is columns and columns are second 
    int height = array2d.length; // height is rows and rows are first 

    BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); 
    Graphics2D g2d = image.createGraphics(); // default color of image is 0 no need to paint background, just draw with color diferent than 0 
    //g2d.setColor(Color.WHITE);    // default brush color is different than 0, expicitly setting is unnecesery 
    //BasicStroke bs = new BasicStroke(1); 
    //g2d.setStroke(bs);      // default is 1 pixel expicitly setting is unnecesery 

    g2d.drawLine(x1, y1, x2, y2); // paint line on image 

    int[] pixels = ((DataBufferInt) image.getRaster().getDataBuffer()).getData(); 
    for (int i = 0, row = 0, col = 0; i < pixels.length; i++) { 
     array2d[row][col] = pixels[i] == 0 ? 0 : 1; // no performance difference vs if/else just readability 
     //array2d[row][col] = pixels[i]; // if you write it like this you will be "painting" with '-1's instead of '1's and save one if/else 
     col++; 
     // if is more readable here no performance difference vs ternary 
     if (col == width) { 
      col = 0; 
      row++; 
     } 
    } 
    g2d.dispose(); 
} 

只有其他地方来提高性能在所有不把它转换成二维数组就像我前面提到的访问值。但是如果你想用数字1而不是默认-1来“绘制”,你将不得不循环通过像素数组来代替-1。

+0

我必须运行这样的代码,每秒多次表现如何? – Llewv

+0

@Llewv我的例子是使用Graphics画出一条线。我怀疑我可以使用自定义代码更高效。只有性能达到我可以做的事情就是转换为int数组。 getRGB()可能很慢。要快速转换为int数组,请查看此[问题](http://stackoverflow.com/questions/6524196/java-get-pixel-array-from-image)。 – MatheM