Reputation: 133
Suppose that I have the given 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
};
Would there be a way to draw graphics into that array? For example assume that we have a way to access the data in this array by an x and y coordinate could we make a method that would put a line through this array dependant on 2 coordinates. The code would look something like this:
public void drawLine(int x1, int y1, int x2, int y2) {
...
}
And would transfer something like this:
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
};
Into this:
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
};
You would have to be able to pass in any set of coordinates and have a calculated line placed through the array. How would I implement this?
Calling drawLine(1,0,3,4) would create something like:
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
};
Also if your up to it is there a way I could specify any number of points and have them all connected and then filled in? (No I don't want to use any libraries).
Upvotes: 1
Views: 1777
Reputation: 811
Very cheaty way to do it (without implementing the drawing logic yourself) would be to use BufferedImage with the dimensions of your array and draw on that. After drawing the line you want you would iterate over the pixels of the BufferedImage and check which pixels are painted.
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
}
Usage
int[][] arr = new int[5][5];
drawToArray(arr, 0, 0, 2, 5);
This example assumes that your array is two dimensional and that each row is of same length. If you want to use one dimensional array, you will have to define its width and height yourself. Also instead of
array2d[row][column] = 0;
you would have
array1d[row*width + column] = 0;
Edit 1: edited my answer to be more general
Edit 2: Considering performance
I doubt that I can improve the drawLine method so only place for improvement is conversion to 2d array. It is possible to get the array of pixels represented as integer values from Image and convert that to 2d array. I updated the draw ToArray method and left commented out lines there as explanation.
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();
}
Only other place where to improve performance is to not convert it to 2d array at all and access the values like I mentioned before. But if you want to "paint" with number 1 instead of default -1 you will have to loop trough the array of pixels anyway to replace the -1s with 1s.
Upvotes: 2