我想使用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));
}
}
}
答案 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
方法检查它是否在多边形中。