0

立方体を形成するために線を 1 つずつ接続して描画される 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 !");

}
}
4

1 に答える 1

2



ここには 2 つの問題があります。ArrayIndexOutOfBoundsException と、不幸な偶然です。

Flood メソッドには、テストした前のポイントからあらゆる方向にポイントを生成するループが含まれていますが、いつ停止するかはわかりません。その結果、image.getRGB(int,int) が呼び出されると例外がスローされ、300x300 領域の外にポイントが生成される可能性があります。
一般に、配列の要素に対して操作をループするときは、配列の制限を覚えておくことをお勧めします。例えば:

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)

また、塗りつぶしを開始するポイントはたまたま立方体の作図線の 1 つにあるため、スペースではなく線が塗りつぶされます。開始するポイントを選択するときは、より注意してください。

floodFill(image, 60, 160, java.awt.Color.yellow.hashCode());

動作するはずです。

お役に立てれば。

于 2012-11-26T19:19:12.297 に答える