在8连接边界填充中的坐标超出界限

时间:2016-04-01 16:17:50

标签: java indexoutofboundsexception fill

我想使用8连接边界填充填充多边形。 4连接边界填充的代码工作。但是,当我添加四个额外的语句来测试8连接边界填充的对角线位置时,我得到 ArrayIndexOutOfBoundsException:Coordinate out of bounds!错误。有什么问题以及如何解决?

private void bfill(int x, int y, Color fillColour, Color borderColour){
    Stack<Point> points = new Stack<>();
    points.add(new Point(x, y));
    while(!points.isEmpty()) {
        Point currentPoint = points.pop();
        x = currentPoint.x;
        y = currentPoint.y;
        Color interiorColour = new Color(bi.getRGB(x, y));
        if (!interiorColour.equals(borderColour) && !interiorColour.equals(fillColour)){
            setPixel(x, y); //draw pixel
            points.push(new Point(x+1, y));
            points.push(new Point(x-1, y));
            points.push(new Point(x, y+1));
            points.push(new Point(x, y-1));
            //Error occurs when the next four lines are uncommented for 8-connected boundary fill
            /*points.push(new Point(x+1, y+1));
            points.push(new Point(x+1, y-1));
            points.push(new Point(x-1, y-1));
            points.push(new Point(x-1, y+1));*/
        }
    }
}

编辑:根据gpasch的回答,我加入了边界检查。但是,该程序无休止地运行。边界检查有什么问题?

if (!interiorColour.equals(borderColour) && !interiorColour.equals(fillColour)){
    if (x > -1 && y > -1 && x < getWidth() && y < getHeight()){
        setPixel(x, y); //draw pixel
        if (x+1 < getWidth())   points.push(new Point(x+1, y));
        if (x-1 > -1)           points.push(new Point(x-1, y));
        if (y+1 < getHeight())  points.push(new Point(x, y+1));
        if (y-1 > -1)           points.push(new Point(x, y-1));

        if (x+1 < getWidth() && y+1 < getHeight())  points.push(new Point(x+1, y+1));
        if (x+1 < getWidth() && y-1 > -1)           points.push(new Point(x+1, y-1));
        if (x-1 > -1 && y-1 > -1)                   points.push(new Point(x-1, y-1));
        if (x-1 > -1 && y+1 > getHeight())          points.push(new Point(x-1, y+1));
        }
    }
}

2 个答案:

答案 0 :(得分:1)

(x,y)超出范围。

您需要检查是否

(X>-1 && x<width) &&  (y>-1 && y<height)

添加积分时的情况相同(如果您想避免以后出现问题)。

如果有任何(x + 1,y),......等超出范围,请不要添加。

-

您必须按如下方式限制边界检查:

Color interiorColour = null;
if (x > -1 && y > -1 && x < getWidth() && y < getHeight()) { 
  interiorColour=new Color(bi.getRGB(x, y));
  if (!interiorColour.equals(borderColour) && !interiorColour.equals(fillColour)){
        setPixel(x, y); //draw pixel
        if (x+1 < getWidth())   points.push(new Point(x+1, y));
        if (x-1 > -1)           points.push(new Point(x-1, y));
        if (y+1 < getHeight())  points.push(new Point(x, y+1));
        if (y-1 > -1)           points.push(new Point(x, y-1));

        if (x+1 < getWidth() && y+1 < getHeight())  points.push(new Point(x+1, y+1));
        if (x+1 < getWidth() && y-1 > -1)           points.push(new Point(x+1, y-1));
        if (x-1 > -1 && y-1 > -1)                   points.push(new Point(x-1, y-1));
        if (x-1 > -1 && y+1 < getHeight())          points.push(new Point(x-1, y+1));
  }
}

-

在进一步考虑时,您的解决方案会遇到以下问题:访问的点不会被排除,因此可以反复访问它们,从而导致可能永无止境的程序。我不明白你的算法的全部含义,但我建议如下:

a)定义一个数组:

boolean[] visited=new boolean[width*height];
for(i=0; i<visited.length; i++) visited[i]=false;

b)当你进入循环并有一个点(x,y) - 弹出后:

    if(visited[x+y*width]) continue;        
    visited[x+y*width]=true;

c)按如下方式调整检查:

    if (x+1 < width)  if(!visited[x+1+y*width]) points.push(new Point(x+1, y));
    if (x-1 > -1)     if(!visited[x-1+y*width])      points.push(new Point(x-1, y));
    if (y+1 < height) if(!visited[x+(y+1)*width]) points.push(new Point(x, y+1));
    if (y-1 > -1)    if(!visited[x+(y-1)*width])       points.push(new Point(x, y-1));

与其他四项检查类似。

堆栈最多可以达到宽度*高度的大小,然后它将减少到0。

另请注意,错误y + 1&gt; getHeight()应该是y + 1&lt;的getHeight()。

答案 1 :(得分:0)

根据gpasch的更新答案,我将访问数组包含在边界检查中。该计划终止。然而,它填满了整个窗口。

我测试了x和y值,因为每个点都会弹出。它们超出了多边形的边界。多边形外部的点与多边形内的点具有相同的颜色。两者既不是边框颜色也不是填充颜色。因此,它们被推到堆叠上,当弹出时,用填充颜色着色。

需要进行边界检查,但应将其限制在多边形的边界,而不是窗口的边界。所以,一旦我在弹出后得到一个点(x,y),我会使用Polygon对象的contains方法检查它是否在多边形中。