边界填充错误地停止递归?

问题描述 投票:0回答:1

我一直在尝试使用我进行设置的 Visual Studio 代码在我的 m1 mac 上执行一个简单的 边界填充 程序,包括配置默认构建任务的所有库,并且构建进展顺利。

但问题是当窗口可见时,程序有一个鼠标单击事件侦听器,单击时应该开始用所需的颜色填充区域,但似乎仅在绘制一条线后就停止了。

这是我的程序,

#include<stdio.h>
#include <GLUT/glut.h>

int xmin, ymin, xmax, ymax; //Polygon boundaries

float FillColor[3] = {1.0, 0.0, 0.0};  //Color to be filled - red
float BorderColor[3] = {0.0, 0.0, 0.0};  // Border color of polygon - black

void setPixel(int x, int y)
{
    glBegin(GL_POINTS);
        glColor3fv(FillColor);
        glVertex2i(x, y);
    glEnd();
    glFlush();
}
void display()
{
    glClear(GL_COLOR_BUFFER_BIT);

    //Drawing polygon
    glColor3fv(BorderColor);
    glLineWidth(6);
    glBegin(GL_LINES);
        glVertex2i(xmin, ymin);
        glVertex2i(xmin, ymax);
    glEnd();
    glBegin(GL_LINES);
        glVertex2i(xmax, ymin);
        glVertex2i(xmax, ymax);
    glEnd();
    glBegin(GL_LINES);
        glVertex2i(xmin, ymin);
        glVertex2i(xmax, ymin);
    glEnd();
    glBegin(GL_LINES);
        glVertex2i(xmin, ymax);
        glVertex2i(xmax, ymax);
    glEnd();
    glFlush();
}
void BoundaryFill(int x,int y)
{
    float CurrentColor[3];
    glReadPixels(x, y, 1.0, 1.0, GL_RGB, GL_FLOAT, CurrentColor);

    // if CurrentColor != BorderColor and CurrentColor != FillColor
    if((CurrentColor[0] != BorderColor[0] && (CurrentColor[1]) != BorderColor[1] &&
       (CurrentColor[2])!= BorderColor[2]) && (CurrentColor[0] != FillColor[0] &&
       (CurrentColor[1]) != FillColor[1] && (CurrentColor[2]) != FillColor[2]))
    {
        setPixel(x, y);
        BoundaryFill(x+1, y);
        BoundaryFill(x-1, y);
        BoundaryFill(x, y+1);
        BoundaryFill(x, y-1);
        //Using 4-connected approach, remove comment from below lines to make it 8-connected approach
        BoundaryFill(x+1, y+1);
        BoundaryFill(x+1, y-1);
        BoundaryFill(x-1, y+1);
        BoundaryFill(x-1, y-1);
    }
}
void mouse(int btn, int state, int x, int y)
{
    if(btn == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
    {
        printf("%d, %d\n", x, y);
        BoundaryFill(x, 500-y);
    }
}

void init()
{
    glClearColor(0.101, 1.0, 0.980, 1.0); //Background color - cyan
    glMatrixMode(GL_PROJECTION);
    gluOrtho2D(0, 500, 0, 500);
}
int main(int argc, char** argv)
{
    printf("Window size - 500x500 i.e. range of x and y is 0 -> 500\n");
    printf("\nEnter polygon boundaries:-\n");
    printf("Enter xmin: ");
    scanf("%d", &xmin);
    printf("Enter ymin: ");
    scanf("%d", &ymin);
    printf("Enter xmax: ");
    scanf("%d", &xmax);
    printf("Enter ymax: ");
    scanf("%d", &ymax);

    glutInit(&argc, argv);
    glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
    glutInitWindowSize(500, 500);
    glutCreateWindow("Boundary-Fill Algorithm");

    init();
    glutDisplayFunc(display);
    glutMouseFunc(mouse);
    glutMainLoop();
    return 0;
}

请检查图像——在此阶段之后,递归停止,这意味着以 8 个连接的方法填充更多像素。

enter image description here

c macos opengl glut
1个回答
0
投票

正交投影覆盖 [0, 500]^2 像素的区域,而算法假设 [0, 500)^2 像素的区域。请注意包含范围和排除范围之间的差异。 这可能会导致

glReadPixels
读取您期望读取的位置左边(和/或下方)的像素值,从而破坏算法。要解决此问题,请对
glOrtho2D
使用不同的尺寸:

gluOrtho2D(0, 499, 0, 499);

另外,注意

glReadPixels
的宽度和高度参数应为整数,即:

glReadPixels(x, y, 1, 1, GL_RGB, GL_FLOAT, CurrentColor);

并且直接比较浮点值并不是一个好主意(请参阅 StackOverflow 上的其他地方)。相反,使用这样的东西:

#include <math.h>

int isEqualFloat(float x, float y)
{
    return fabs(x - y) < 0.001F;
}

我假设使用

glReadPixels
是出于教育目的。更好的方法是为“访问的”像素存储一个布尔矩阵,这样就无需比较浮点值中的颜色并从 GPU 内存中检索数据。

最后,使用最新的 Mac 可能会产生影响。对于某些低分辨率程序,操作系统决定重复每个像素以避免窗口非常小。然而,这实际上使分辨率加倍,而 OpenGL 并不知道。

© www.soinside.com 2019 - 2024. All rights reserved.