java - 8 连通边界填充中的坐标超出范围

标签 java indexoutofboundsexception fill

我想使用 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/

相关文章:

java - AbstractTableModel - 不返回 getRowCount()

java - 当我将图像路径传递给其他 Activity 时,会发生 StringIndexOutOfBoundsException

android - 将多边形添加到 map 时出现 IndexOutOfBoundsException

reactjs - React JSX - 用图像填充 svg

css - "-webkit-text-fill-color"和 "color"之间的区别?

javascript - 将 CSS 应用于 SVG 时出现问题

java - 将 Spring Boot 应用程序作为 Docker 镜像启动时无法解析配置类

java - LinkedHashSet 不删除重复项

android - 删除 ArrayList 上的元素会在 ArrayAdapter 上抛出 IndexOutOfBoundsException

java - 是否可以使用一个对象在 JTable 字段中显示不同的数据?