C中的边界填充算法不起作用(计算机图形学 - C编程)

时间:2014-09-27 18:46:17

标签: c graphics turbo-c bgi

我正在尝试使用简单的边界填充方法(使用4种连接方法)来填充矩形。我做了如下(代码如下),但矩形没有得到正确填充:它到达矩形的一半部分时停止填充。

但是在尝试填充圆圈时,相同的代码工作正常。任何人都可以帮我解决问题吗?

提前致谢

#include <stdio.h>
#include <conio.h>
#include <graphics.h>

void boundfill(int xc, int yc, int r, int b) {
    int cur;
    cur = getpixel(xc, yc);
    if (cur != b && cur != r) {
        putpixel(xc, yc, r);
        delay(1);

        boundfill(xc + 1, yc, r, b);
        boundfill(xc - 1, yc, r, b);
        boundfill(xc, yc + 1, r, b);
        boundfill(xc, yc - 1, r, b);
    }
}

void main() {
    int gd = DETECT, gm;
    initgraph(&gd, &gm, "..\\bgi");

    rectangle(100, 100, 300, 300);
    boundfill(105, 105, 4, WHITE);

    getch();
    closegraph();
}

输出:

Output 1

但是当我对矩形使用以下坐标时,它工作正常。给定坐标:

rectangle(50, 50, 100 ,100);
boundfill(55, 55, 4, WHITE);

为此,输出为:

Output 2

2 个答案:

答案 0 :(得分:0)

您使用的是什么平台?

  • 是32位还是16位可执行文件?

BGI是非常古老的Borland gfx API,如果它是原创的Borland BGI,仍然用于学习目的,那么你正在创建16位DOS应用程序。还有用于Windows和Linux的BGI包装器/模拟器,在这种情况下,它取决于您的编译器设置。

可能出错:

  1. <强>堆/堆

    在16位DOS模式下,您只能看到前1 MB的内存空间,其中640KB可用于整个系统。在您的程序/项目/编译器设置中,还有其他约束,例如应用程序的初始/最大堆和堆栈大小。如果设置得太低,那么你可能会遇到堆栈问题,在这种情况下它应该抛出一个异常,但根据我的经验,我看到很多奇怪的东西然后缺少异常。

    当您填充100x100像素区域时,您的递归最多为10000次,并且您的递归调用(16位大小写)包含:

    1 x return address segment+offset = 4 Byte
    4 x int16 operand = 8 Byte
    1 x int local variable = 2 Byte
    

    所有14字节(在某些C / C ++引擎上截断为16字节)不计算附加数据需要sublikes如putpixel ...乘以递归计数,你肯定在16位DOS上肯定高于安全性。要检查一下:

    • 每次填充应停在同一地点(如果代码中没有更多处理)
    • 如果你将一些变量添加到函数头中,它应该在
    • 之前停止
    • 更改堆/堆栈限制也应该影响这个

    修复此消除所有不必要的递归,例如b,r是常量,因此它们可以是全局变量。如果您在返回之前将xc,yc设置回原始状态,则可以使用&xc,&yc。你的cur局部变量可以是静态的。这将消除递归中的所有分配,只保留返回地址。

  2. gfx模式

    BGI主要用于16种色彩模式,分辨率越高,越过64KB障碍。如果您的BGI驱动程序出现问题,可能会挂起或停止绘图。在这种情况下,无论子弹#1 ,停止都会发生在同一个地方。为了避免这种改变BGI驱动程序,使用不同的分辨率或更好的模拟器

答案 1 :(得分:0)

没有其他信息 - 这就像堆栈溢出一样。我的假设基于以下内容:

  1. 您的算法过于递归。
  2. 问题出现在一个较大的矩形
  3. 您提供的填充模式与您的程序刚刚初步“停止”(实际崩溃)的假设一致。也就是说,您的递归路径首先水平填充,然后垂直填充。
  4. 除了讨论这种特定填充算法的有效性之外,请注意,只有当递归深度具有合理的限制时,才使用递归算法。

    例如,在平衡二叉树上使用递归是可以的,因为这样的树深度(以及因此递归深度)与树大小呈对数增长。另一方面,使用递归进行链表操作是不合理的。

    如果你坚持使用这个特定的算法,我相信你应该摆脱递归。您可以将起始点放在队列中,然后在循环中弹出队列中的一个点,绘制并将其邻居推入队列。与BFS算法类似。