【问题标题】:Filled Bresenham circle with some color in OpenGL在 OpenGL 中用一些颜色填充 Bresenham 圆
【发布时间】:2014-03-25 18:53:32
【问题描述】:

我正在使用此 Bresenham 算法来绘制圆。此代码有效,但我需要实心圆圈,而不仅仅是边框。

这是我的代码:

void setPixel(int x,int y)  {  
    glBegin(GL_POINTS); 
    glColor3f(0.0f, 1.0f, 0.0f);
    glPointSize (20.0);
    glVertex2i(x,y);
    glEnd();
}

void BresenhamKrug(int xCenter, int yCenter,int r){ //napravite parametarski poziv
int x=0,y=r;
int d=3-(2*r);

glColor3f(0.5,0.3,1.); 


while(x<=y)
{
    setPixel(xCenter+x,yCenter+y);  setPixel(xCenter+y,yCenter+x);
    setPixel(xCenter-x,yCenter+y);  setPixel(xCenter+y,yCenter-x); 
    setPixel(xCenter-x,yCenter-y);  setPixel(xCenter-y,yCenter-x); 
    setPixel(xCenter+x,yCenter-y);  setPixel(xCenter-y,yCenter+x); 

    if (d<0)
        d += (4*x)+6;
    else{
          d += (4*(x-y))+10;
          y--;
    }

    x++;
}
glFlush();
}

有什么办法吗?

【问题讨论】:

  • 这是作业吗?因为如果不是这样,通过立即模式点绘制的 Bresenham 光栅化是使用 OpenGL 绘制圆的效率最低的方法。
  • 不,我在一些图片中使用了 bresenham 圆点。因为我想用这个算法画圆。

标签: c++ opengl glut bresenham


【解决方案1】:

您可以将点保存在数组中并改为绘制多边形,或者triangle fans

glBegin(GL_POLYGON);

或:

void BresenhamKrug(int xCenter, int yCenter,int r){ //napravite parametarski poziv
    int x=0,y=r;
    int d=3-(2*r);

    glColor3f(0.5,0.3,1.); 

    glBegin(GL_POLYGON);

    while(x<=y)
    {
        glVertex2i(xCenter+x,yCenter+y);  glVertex2i(xCenter+y,yCenter+x);
        glVertex2i(xCenter-x,yCenter+y);  glVertex2i(xCenter+y,yCenter-x); 
        glVertex2i(xCenter-x,yCenter-y);  glVertex2i(xCenter-y,yCenter-x); 
        glVertex2i(xCenter+x,yCenter-y);  glVertex2i(xCenter-y,yCenter+x); 

        if (d<0)
            d += (4*x)+6;
        else{
              d += (4*(x-y))+10;
              y--;
        }

        x++;
    }
    glEnd();
    glFlush();
}

但不确定一个简单的圆方程是不够的..drawing circle,光栅化是由 openGL 提供的handled

【讨论】:

  • 它不是精确的圆,但它非常接近,因为 bresham alg 非常好。
【解决方案2】:

最简单的解决方案是修改算法,这样就不用在边缘周围绘制像素,而是用线连接点。

void drawLine(const float x1, const float y1, const float x2, const float y2) {
    const bool steep = (fabs(y2 - y1) > fabs(x2 - x1));
    if(steep) {
        std::swap(x1, y1);
        std::swap(x2, y2);
    }

    if(x1 > x2) {
        std::swap(x1, x2);
        std::swap(y1, y2);
    }

    const float dx = x2 - x1;
    const float dy = fabs(y2 - y1);

    float error = dx / 2.0f;
    const int ystep = (y1 < y2) ? 1 : -1;
    int y = (int)y1;

    const int maxX = (int)x2;

    for(int x=(int)x1; x<maxX; x++) {
        if(steep) {
            setPixel(y,x);
        }
        else {
            setPixel(x,y);
        }

        error -= dy;
        if(error < 0) {
            y += ystep;
            error += dx;
        }
    }
}

void BresenhamKrug(int xCenter, int yCenter,int r){ //napravite parametarski poziv
    int x=0,y=r;
    int d=3-(2*r);
    glColor3f(0.5,0.3,1.);
    while(x<=y) {
        drawLine(xCenter+x,yCenter+y,  xCenter+y,yCenter+x);
        drawLine(xCenter-x,yCenter+y,  xCenter+y,yCenter-x); 
        drawLine(xCenter-x,yCenter-y,  xCenter-y,yCenter-x); 
        drawLine(xCenter+x,yCenter-y,  xCenter-y,yCenter+x); 
        if (d<0)
            d += (4*x)+6;
        else{
            d += (4*(x-y))+10;
            y--;
        }
        x++;
    }
    glFlush();
}

出于所有意图和目的,Bresenham 的线算法可能是最适合此的。

【讨论】:

  • OpenGL 已经提供了线和填充三角形光栅化。也无需重新发明轮子。
  • 鉴于海报明显无视性能,我认为问题是寻找围绕 Bresenham 的算法解决方案,而不是关于 OpenGL 原语的讲座。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-03-17
  • 1970-01-01
  • 2019-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多