2016-06-09 114 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