首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Bresenham线绘制算法

Bresenham线绘制算法
EN

Code Review用户
提问于 2015-08-25 17:12:47
回答 2查看 2.9K关注 0票数 5
代码语言:javascript
复制
int Octet(double m, int Ax, int Ay, int Bx, int By)
{
    int octetNo = -1;
    double dx = Bx - Ax;
    double dy = By - Ay;

    //m = dy / dx;

    if(0<=m && m<=1)
    {
        if(Ax<Bx) octetNo = 1;
        else if(Bx<Ax) octetNo = 5;
    }
    else if(0>=m && m>=-1)
    {
        if(Bx<Ax) 
            octetNo = 4;
        else if(Ax<Bx) octetNo = 8;
    }
    else if(m>1)
    {
        if(Ay<By) octetNo = 2;
        else if(By<Ay) octetNo = 6;
    }
    else if(-1>m)
    {
        if(Ay<By) octetNo = 3;
        else if(By<Ay) octetNo = 7;
    }   

    return octetNo;
}

int NextDiIfDiIsGreaterThanOrEqualtoZero(double m, int di, int x1, int y1, int x2, int y2)
{
    int di_plus_1 = -1;
    int dx = x2 - x1;
    int dy = y2 - y1;

    int octet = Octet(m, x1, y1, x2, y2);

    switch(octet)
    {
    case 1:
    case 5:
        di_plus_1 = di - 2 * (dx - dy); 
        break;
    case 2:
    case 6:
        di_plus_1 = di + 2 * (dx - dy); 
        break;
    case 3:
    case 7:
        di_plus_1 = di - 2 * (dx + dy); 
        break;
    case 4:
    case 8:
        di_plus_1 = di + 2 * (dx + dy); 
        break;
    }

    return di_plus_1;
}

int NextDiIfDiIsSmallerThanZero(double m, int di, int x1, int y1, int x2, int y2)
{
    int di_plus_1 = -1;
    int dx = x2 - x1;
    int dy = y2 - y1;

    int octet = Octet(m, x1, y1, x2, y2);

    switch(octet)
    {
    case 1:
    case 5:
        di_plus_1 = di - 2 * dy; 
        break;
    case 2:
    case 6:
        di_plus_1 = di + 2 * dx; 
        break;
    case 3:
    case 7:
        di_plus_1 = di - 2 * dx; 
        break;
    case 4:
    case 8:
        di_plus_1 = di + 2 * dy; 
        break;
    }

    return di_plus_1;
}

int InitialValueOfDi(double m, int x1, int y1, int x2, int y2)
{
    int init_di = -1;
    int dx = x2 - x1;
    int dy = y2 - y1;

    int octet = Octet(m, x1, y1, x2, y2);

    switch(octet)
    {
    case 1:
    case 5:
        init_di = dx - 2 * dy; 
        break;
    case 2:
    case 6:
        init_di = 2 * dx - dy; 
        break;
    case 3:
    case 7:
        init_di = (-2) * dx - dy; 
        break;
    case 4:
    case 8:
        init_di = 2 * dy + dx; 
        break;
    }

    return init_di;
}

void BresLine(int x1, int y1, int x2, int y2, int color)
{
    int dy = y2 - y1;
    int dx = x2 - x1;
    double m = (double)dy/(double)dx;
    int di = InitialValueOfDi(m, x1, y1, x2, y2);
    int limit = ((abs(dx)>abs(dy))?abs(dx):abs(dy))/2;
    int x = x1;
    int y = y1;

    for(int i=0 ; i<=limit; i++)
    {
        PlotPixel(x, y, color);

        if(di>=0)
        {
            di = NextDiIfDiIsGreaterThanOrEqualtoZero(m, di, x1, y1, x2, y2);
            y++;            
        }
        else
        {
            di = NextDiIfDiIsSmallerThanZero(m, di, x1, y1, x2, y2);            
        }       
        x++;
    }
}
EN

回答 2

Code Review用户

发布于 2015-08-25 18:33:55

免责声明:我对C++一无所知,但我会尽我所能帮助你。

总的来说,您的代码看起来不错。A+的可读性!可能是某个地方失踪的地方,但没什么大的。不过,您的代码很容易阅读和遵循。

在您的BresLine()上,您有以下内容:

代码语言:javascript
复制
int dy = y2 - y1;
int dx = x2 - x1;
double m = (double)dy/(double)dx;
[...]
int limit = ((abs(dx)>abs(dy))?abs(dx):abs(dy))/2;

你可以试着把那个abs()存储在某个地方,重新命名它的时候刮胡子。

您有NextDiIfDiIsGreaterThanOrEqualtoZero()NextDiIfDiIsSmallerThanZero()函数。他们有巨大的名字。代码几乎一样。我建议如下:

代码语言:javascript
复制
int NextDi(double m, int di, int x1, int y1, int x2, int y2)
{
    int di_plus_1 = -1;
    int dx = x2 - x1;
    int dy = y2 - y1;

    int octet = Octet(m, x1, y1, x2, y2);

    switch(octet)
    {
        case 1:
        case 5:
            di_plus_1 = di - 2 * (di > 0 ? dx - dy : dy); 
            break;
        case 2:
        case 6:
            di_plus_1 = di + 2 * (di > 0 ? dx - dy : dx); 
            break;
        case 3:
        case 7:
            di_plus_1 = di - 2 * (di > 0 ? dx - dy : dx); 
            break;
        case 4:
        case 8:
            di_plus_1 = di + 2 * (di > 0 ? dx - dy : dy); 
            break;
    }



    return di_plus_1;
}

这不是地球上最漂亮的东西,但可能对你有用。要做到这一点,你什么都不用改变!只需删除if on BresLine即可。通过一些按位操作,您可以将此代码减少很多!

如果你看到什么,请告诉我。我还没有触及剩下的函数,但是我特别担心Octet函数。

票数 5
EN

Code Review用户

发布于 2015-08-26 01:47:32

Bugs

考虑到这几点:

int极限=(abs(Dx)>abs(Dy))?abs(Dx):abs(Dy)/2;int x= x1;int y= y1;for(int i=0;i<=limit;i++) { PlotPixel(x,y,color);if(di>=0) { di =某事;y++;

我可以立即推断出以下问题:

  1. 您的程序将只绘制所请求的线的一半左右,因为它会绘制limit+1像素数,而limit是最长维度长度的一半。
  2. 您的程序无法绘制垂直线,因为每个循环无条件地递增x。这也意味着它不可能画出比45度更陡的线。
  3. 您的程序只有x++,而没有x--。但是如果x2x1小,那么你就画错了方向。y也是如此。

进一步的研究表明,程序也没有正确地处理水平线(y在第一次迭代时增加)。

如果您实际运行代码并绘制结果,这些bug看起来应该是非常明显的。我建议多花点时间测试。

票数 2
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/101890

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档