我想使用 8 连通边界填充来填充多边形。 4 连通边界填充的代码有效。但是,当我添加四个附加语句来测试 8 连接边界填充的对角线位置时,我收到 ArrayIndexOutOfBoundsException:坐标超出范围! 错误。问题是什么以及如何解决?
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));
}
}
}
最佳答案
(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>getHeight(),应该是 y+1 < getHeight()。
关于java - 8 连通边界填充中的坐标超出范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36361119/