I have an assigment where I need to animate a 3d cube being drawn with lines connecting one by one to form the cube. after that, each side of the cube needs to be colored in a different color, once each is colored in, pause, then color the next side.
How do I go about doing this? I have provided my code, I try filling in the background square right after the cube is made but I get the following error:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Coordinate out of bounds!
at sun.awt.image.IntegerInterleavedRaster.getDataElements(IntegerInterleavedRaster.java:203)
at java.awt.image.BufferedImage.getRGB(BufferedImage.java:881)
at drawCube.floodFill(drawCube.java:50)
at drawCube.main(drawCube.java:181)
here is my code, let me know what the best way to do this would be.
import java.awt.image.BufferedImage;
import javax.swing.JLabel;
import javax.swing.ImageIcon;
import java.awt.Point;
class drawCube
{
static void fillImage(BufferedImage image, int red, int green, int blue)
{
int packedRGB = packRgb(255,255,255);//white
for (int y=0;y<image.getHeight(null);y++)
{
for (int x=0;x<image.getWidth(null);x++)
image.setRGB(x,y,packedRGB);
}
}
public static void floodFill(BufferedImage image, int x,int y, int fillColor)
{
java.util.ArrayList<Point> examList=new java.util.ArrayList<Point>();
int initialColor=image.getRGB(x,y);
examList.add(new Point(x,y));
while (examList.size()>0)
{
Point p = examList.remove(0); // get and remove the first point in the list
if (image.getRGB(p.x,p.y)==initialColor)
{
x = p.x; y = p.y;
image.setRGB(x, y, fillColor); // fill current pixel
examList.add(new Point(x-1,y)); // check west neighbor
examList.add(new Point(x+1,y)); // check east neighbor
examList.add(new Point(x,y-1)); // check north neighbor
examList.add(new Point(x,y+1)); // check south neighbor
// waitNS(1); // delay to see floodFill() work
// repaintImage(image);
}
}
}
private static void repaintImage(BufferedImage image)
{
_imageLabel.setIcon(new ImageIcon(image));
_imageLabel.repaint();
}
public static void waitNS(long ns)
{
try { Thread.sleep(ns); } // Pause ns
catch (Exception ignore) { ; }
}
public static int packRgb(int r,int g,int b)
{
return (r*256+g)*256+b;
}
static JLabel _imageLabel;
public static void main(String[] args) throws Exception
{
// create an 300x300 RGB image
BufferedImage image=new BufferedImage(300,300,BufferedImage.TYPE_INT_RGB);
// fill the image with green color
fillImage(image,0,255,0);
JLabel imageLabel=new JLabel();
_imageLabel = imageLabel; // make it global
imageLabel.setIcon(new ImageIcon(image));
imageLabel.setText("Filling the box with yellow color ...");
javax.swing.JFrame window=new javax.swing.JFrame();
window.setTitle("Cube Experiment");
window.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);
window.add(imageLabel);
window.pack();
window.setVisible(true);
java.awt.Graphics2D gr=(java.awt.Graphics2D) image.getGraphics();
int x1 = 50; int y1 = 150;
int x2 = 150; int y2 = 150;
int x3 = 150; int y3 = 250;
int x4 = 50; int y4 = 250;
gr.setColor(new java.awt.Color(0,0,0)); // blue
gr.setStroke(new java.awt.BasicStroke(2)); // set pen width to 2 pixels
gr.drawLine(50, 150, 150, 150);
repaintImage(image);
waitNS(500);
gr.drawLine(150, 150, 150, 250);
repaintImage(image);
waitNS(500);
gr.drawLine(150, 250, 50, 250);
repaintImage(image);
waitNS(500);
gr.drawLine(50, 250, 50, 150);
repaintImage(image);
waitNS(500);
gr.drawLine(0, 300, 100, 300);
repaintImage(image);
waitNS(500);
gr.drawLine(0, 300, 50, 250);
repaintImage(image);
waitNS(500);
gr.drawLine(100, 300, 150, 250);
repaintImage(image);
waitNS(500);
gr.drawLine(100, 300, 100, 200);
repaintImage(image);
waitNS(500);
gr.drawLine(0, 285, 0, 200);
repaintImage(image);
waitNS(500);
gr.drawLine(0, 200, 100, 200);
repaintImage(image);
waitNS(500);
gr.drawLine(0, 200, 50, 150);
repaintImage(image);
waitNS(500);
gr.drawLine(100, 200, 150, 150);
repaintImage(image);
waitNS(500);
// fill the square with yellow color
int yellow = packRgb(255,255,0);
int black = packRgb(0,0,0);
//floodFill(image,(x1+x2)/2, (y1+y4)/2, yellow);//flood fill at center
imageLabel.setIcon(new ImageIcon(image));
imageLabel.setText("Completed !");
}
}
There are two problems here: the ArrayIndexOutOfBoundsException and an unfortunate coincidence.
Your flood method includes a loop that generates points in every direction from the previous point tested, but doesn’t say when to stop. The result is that a point can be generated outside of the 300×300 area, throwing an exception when image.getRGB(int,int) is called.
It’s generally a good idea to remember the limits of your array when looping operations on its elements. For example:
Or less precisely:
Also, the point you start the flood from happens to lie on one of the construction lines of the cube, so the lines are filled instead of the spaces. Be more careful when choosing the points to start at.
should work.
Hope this helps.