【问题标题】:stack overflow issue with byte framebuffer array fill command字节帧缓冲区数组填充命令的堆栈溢出问题
【发布时间】:2013-08-08 12:32:44
【问题描述】:

大家好,我目前正在开发我自己的自定义帧缓冲区并将原语绘制到其中。哪个工作正常。

然而,我的问题是将基元填充为屏幕上的纯色。比如本例中的圆圈。

问题是我试图填补它,我得到一个堆栈溢出错误(这意味着递归函数永远不会结束)。

这是我用来填充区域的递归函数...

private void filler(int position, byte r, byte g, byte b)
{

    buffer[position] = r;
    buffer[position + 1] = g;
    buffer[position + 2] = b;
    int northPosition = position - rowLength;
    int southPosition = position + rowLength;
    int westPosition = position - 3;
    int eastPosition = position + 3;
    //fills squares west of the current
    /**/
    System.out.println(position);
    //fills squares to the east of the current 
    if(buffer[eastPosition] != r && buffer[eastPosition + 1] != g && buffer[eastPosition + 2] != b)
    {
        System.out.println("runs");
        filler(eastPosition, r, g, b);
    }
    System.out.println(position);
    //fills squares north of the current
    if(buffer[northPosition] != r && buffer[northPosition + 1] != g && buffer[northPosition + 2] != b)
    {
        filler(northPosition,r,g,b);
    }
    //fills squares south of current
    if(buffer[southPosition] != r && buffer[southPosition + 1] != g && buffer[southPosition + 2] != b)
    {
        filler(southPosition,r,g,b);
    }
    //fills squares  west of current
    if(buffer[westPosition] != r && buffer[westPosition + 1] != g && buffer[westPosition + 2] != b)
    {   
        filler(westPosition, r, g, b);
    }
}

请注意,代码的北部和南部部分工作得很好,只有当代码的东部和西部部分一起工作时才会出现错误(但如果我从函数中删除一个或另一个,它们自己工作得很好)。如果有人看到问题,您能否向我解释为什么东西方可能会相互影响?

非常感谢!

【问题讨论】:

  • filler() 的示例输入是什么?
  • 因为它以字节为单位,它描绘了一个特定的位置。可能是 23345,200,0,0
  • 你是东/西没有南/北吗?
  • 很有趣,现在刚刚尝试过,它似乎在东方和西方都很好。删除了南北代码。

标签: java stack-overflow


【解决方案1】:

你的方法永远不会返回。您填充的每个点通常旁边至少有 1 个像素,因此该方法暂时不会返回,而是沿着调用堆栈向下填充该像素。这会导致调用堆栈非常深,并且 stackoverflow 会限制要填充的区域的大小。因此,如果您想使用 java 并填充大面积区域,您应该考虑另一种算法。

【讨论】:

  • 是的,我看的越多,它似乎越接近堆栈跟踪。如果删除其中一个语句,它可以部分填充圆圈......但是我还不想放弃这种方法。
【解决方案2】:

我认为您正在尝试实现 Floodfill 算法(请参阅 german Wikipedia 以获得不错的伪代码实现)。由于您显然使用的是一维数组,因此您必须确保不会跨行(在东/西情况下)或数组的边界(对于所有情况)。

如果下一步将与当前像素在同一行中并且如果它位于数组的边界内,则您只想在东/西方向前进。所以我会像这样改变你的代码(我没有测试它):

private void filler(int position, byte r, byte g, byte b)
{

    buffer[position] = r;
    buffer[position + 1] = g;
    buffer[position + 2] = b;
    int northPosition = position - rowLength;
    int southPosition = position + rowLength;
    int westPosition = position - 3;
    int eastPosition = position + 3;
    //fills squares west of the current
    /**/
    System.out.println(position);
    //fills squares to the east of the current 
    if(eastPosition < buffer.length && eastPosition/rowLength == position/rowLength && buffer[eastPosition] != r && buffer[eastPosition + 1] != g && buffer[eastPosition + 2] != b)
    {
        System.out.println("runs");
        filler(eastPosition, r, g, b);
    }
    System.out.println(position);
    //fills squares north of the current
    if(northPosition >= 0 && buffer[northPosition] != r && buffer[northPosition + 1] != g && buffer[northPosition + 2] != b)
    {
        filler(northPosition,r,g,b);
    }
    //fills squares south of current
    if(southPosition < buffer.length && buffer[southPosition] != r && buffer[southPosition + 1] != g && buffer[southPosition + 2] != b)
    {
        filler(southPosition,r,g,b);
    }
    //fills squares  west of current
    if(westPosition >= 0 && westPosition/rowLength == position/rowLength && buffer[westPosition] != r && buffer[westPosition + 1] != g && buffer[westPosition + 2] != b)
    {   
        filler(westPosition, r, g, b);
    }
}

【讨论】:

  • 是的,这看起来是我正在尝试使用的。并且为了确保我不这样做,我正在检查我在移动到下一个位置之前放置的内容是否相同,因此是 if 语句。在这一点上,我假设它变得如此递归,以至于达到堆栈跟踪限制..当我看着它时,它看起来越来越多..
  • 越过行是我的第一个想法,但整个事情只能在完整的边框下工作,否则会遇到 ArrayIndexOutOfBoundsExceptions。
  • 嗯,我想我知道你在那里尝试了什么。然而西/北/南/东位置只告诉它它需要向哪个方向移动。它在原始位置中的 +3 因为在字节数组中一个位置是 3 个字节(红色、蓝色、绿色)。我选择使用 rbg 来确定它的边界,因为它们的颜色与填充颜色相同。无论如何都会尝试。*编辑*是的,创建了一个超出范围的索引错误=/
【解决方案3】:

也添加边界条件:是否有南/北/东/西位置?

否则向西会跳向北,依此类推,递归很容易。 同样,一旦没有递归,应该会发生索引越界。

【讨论】:

  • 边界条件是 if 条件。形状的轮廓在它们中是相同的 r,g,b 着色,使其有效地充当边界。
  • 在这种情况下,我只能看到一个问题:rowLength 不是三倍。也许是rowLength * 3
猜你喜欢
  • 1970-01-01
  • 2017-02-23
  • 1970-01-01
  • 1970-01-01
  • 2010-11-11
  • 1970-01-01
  • 1970-01-01
  • 2020-08-20
  • 1970-01-01
相关资源
最近更新 更多