画图板--用DDA算法和Bresenham算法画直线

上一篇文章中为了简单起见,直接用了CDC的画直线功能,这几天认真研读了图形学的课本,发现书上的算法都是假定直线斜率-1<m<1的情况下适用的,参考了网上的一些资料,将在任意斜率下画直线的两种算法实现如下:
void Line::Draw_DDA(CDC *pDC)
{//用DDA算法画直线
        int i;

    if(pStart.x==pEnd.x)
    {
        //为竖线
        if(pStart.y<=pEnd.y)
        {
            for(i=pStart.y;i<=pEnd.y;i++)
                pDC->SetPixel(pStart.x,i,m_lPenColor);
        }
        else
        {
            for(i=pEnd.y;i<=pStart.y;i++)
                pDC->SetPixel(pStart.x,i,m_lPenColor);
        }

        return;
    }

    //为横线
    if(pStart.y==pEnd.y)
    {
        if(pStart.x<=pEnd.x)
        {
            for(i=pStart.x;i<=pEnd.x;i++)
                pDC->SetPixel(i,pStart.y,m_lPenColor);
        }
        else
        {
            for(i=pEnd.x;i<=pStart.x;i++)
                pDC->SetPixel(i,pStart.y,m_lPenColor);
        }

        return;
    }

    //为斜线
    double m=(pEnd.y-pStart.y)*1.0/(pEnd.x-pStart.x);
    float fTemp;

    if(abs(m)<=1)
    {
        if(pStart.x<pEnd.x)
        {
            fTemp=pStart.y-m;
            for(i=pStart.x;i<=pEnd.x;i++)
                pDC->SetPixel(i,fTemp+=m,m_lPenColor);
        }
        else
        {
            fTemp=pEnd.y-m;
            for(i=pEnd.x;i<=pStart.x;i++)
                pDC->SetPixel(i,fTemp+=m,m_lPenColor);
        }
        return;
    }

    if(pStart.y<pEnd.y)
    {
        fTemp=pStart.x-1/m;
        for(i=pStart.y;i<=pEnd.y;i++)
            pDC->SetPixel(fTemp+=1/m,i,m_lPenColor);
    }
    else
    {
        fTemp=pEnd.x-1/m;
        for(i=pEnd.y;i<=pStart.y;i++)
            pDC->SetPixel(fTemp+=1/m,i,m_lPenColor);
    }
}


void Line::Draw_Bresenham(CDC *pDC)
{//用Bresenham算法画直线
    int i;

    if(pStart.x==pEnd.x)
    {
        //为竖线
        if(pStart.y<=pEnd.y)
        {
            for(i=pStart.y;i<=pEnd.y;i++)
                pDC->SetPixel(pStart.x,i,m_lPenColor);
        }
        else
        {
            for(i=pEnd.y;i<=pStart.y;i++)
                pDC->SetPixel(pStart.x,i,m_lPenColor);
        }

        return;
    }

    //为横线
    if(pStart.y==pEnd.y)
    {
        if(pStart.x<=pEnd.x)
        {
            for(i=pStart.x;i<=pEnd.x;i++)
                pDC->SetPixel(i,pStart.y,m_lPenColor);
        }
        else
        {
            for(i=pEnd.x;i<=pStart.x;i++)
                pDC->SetPixel(i,pStart.y,m_lPenColor);
        }

        return;
    }

    //为斜线
    float m=(pEnd.y-pStart.y)*1.0/(pEnd.x-pStart.x);
    float p;

    p=2*m-1;
    if(m>0 && m<=1)
    {
        if(pStart.x<pEnd.x)
        {
            while(pStart.x<=pEnd.x)
            {
                pDC->SetPixel(pStart.x++,pStart.y,m_lPenColor);
                if(p>=0)
                {
                    p+=2*m-2;
                    pStart.y++;
                }
                else
                    p+=2*m;
            }
        }
        else
        {
            while(pEnd.x<=pStart.x)
            {
                pDC->SetPixel(pEnd.x++,pEnd.y,m_lPenColor);
                if(p>=0)
                {
                    p+=2*m-2;
                    pEnd.y++;
                }
                else
                    p+=2*m;
            }
        }

        return;
    }

    p=-2*m-1;
    if(m<0 && m>=-1)
    {
        if(pStart.x<pEnd.x)
        {
            while(pStart.x<=pEnd.x)
            {
                pDC->SetPixel(pStart.x++,pStart.y,m_lPenColor);
                if(p>=0)
                {
                    p+=-2*m-2;
                    pStart.y--;
                }
                else
                    p+=-2*m;
            }
        }
        else
        {
            while(pEnd.x<=pStart.x)
            {
                pDC->SetPixel(pEnd.x++,pEnd.y,m_lPenColor);
                if(p>=0)
                {
                    p+=-2*m-2;
                    pEnd.y--;
                }
                else
                    p+=-2*m;
            }
        }

        return;
    }

    p=2/m-1;
    if(m>1)
    {
        if(pStart.y<pEnd.y)
        {
            while(pStart.y<=pEnd.y)
            {
                pDC->SetPixel(pStart.x,pStart.y++,m_lPenColor);
                if(p>=0)
                {
                    p+=2/m-2;
                    pStart.x++;
                }
                else
                    p+=2/m;
            }
        }
        else
        {
            while(pEnd.y<=pStart.y)
            {
                pDC->SetPixel(pEnd.x,pEnd.y++,m_lPenColor);
                if(p>=0)
                {
                    p+=2/m-2;
                    pEnd.x++;
                }
                else
                    p+=2/m;
            }
        }

        return;
    }

    p=-2/m-1;
    if(pStart.y<pEnd.y)
    {
        while(pStart.y<=pEnd.y)
        {
            pDC->SetPixel(pStart.x,pStart.y++,m_lPenColor);
            if(p>=0)
            {
                p+=-2/m-2;
                pStart.x--;
            }
            else
                p+=-2/m;
        }
    }
    else
    {
        while(pEnd.y<=pStart.y)
        {
            pDC->SetPixel(pEnd.x,pEnd.y++,m_lPenColor);
            if(p>=0)
            {
                p+=-2/m-2;
                pEnd.x--;
            }
            else
                p+=-2/m;
        }
    }
}




源代码下载

    窗口重绘还是有问题,郁闷。。。


本文转自Phinecos(洞庭散人)博客园博客,原文链接:http://www.cnblogs.com/phinecos/archive/2007/07/27/833871.html,如需转载请自行联系原作者

上一篇:Linux基础(一):获取Linux CPU 信息


下一篇:学习 Kubernetes 的 Why 和 How - 每天5分钟玩转 Docker 容器技术(114)