我有一个分配,我需要动画一个3d立方体,用逐行连接的线条来形成立方体。在此之后,立方体的每一面都需要以不同的颜色着色,一旦被涂上颜色,暂停,然后为下一面着色。
我该怎么做呢?我提供了我的代码,我尝试在制作多维数据集后立即填充背景方块,但是我收到以下错误:
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)
这是我的代码,让我知道最好的方法是什么。
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 !");
}
}
答案 0 :(得分:2)
这里有两个问题:ArrayIndexOutOfBoundsException和一个不幸的巧合。
您的泛滥方法包括一个循环,该循环在前一个测试点的每个方向上生成点,但不会说何时停止。结果是可以在300x300区域之外生成一个点,在调用image.getRGB(int,int)时抛出异常。
在对元素进行循环操作时,记住数组的限制通常是个好主意。例如:
if(x-1>0) examList.add(new Point(x-1,y)); // check west neighbour
if(x+1<300) examList.add(new Point(x+1,y)); // check east neighbour
if(y-1>0) examList.add(new Point(x,y-1)); // check north neighbour
if(y+1<300) examList.add(new Point(x,y+1)); // check south neighbour
或者不那么精确:
if (p.x>0 && p.y>0 && p.x<300 && p.y<300 && image.getRGB(p.x,p.y)==initialColor)
此外,您开始泛滥的点恰好位于立方体的一条构造线上,因此线条被填充而不是空格。选择要点时要更加小心。
floodFill(image, 60, 160, java.awt.Color.yellow.hashCode());
应该有用。
希望这有帮助。