计算机图形学:3种画直线算法(转)

来源:互联网 发布:淘宝空间在哪里找 编辑:程序博客网 时间:2024/06/06 07:20

 

 

 

计算机图形学:3种画直线算法

分类:C/C++

//---------------------------------------------------------------------
//绘制直线的DDA算法基本函数
//---------------------------------------------------------------------
void LineDDA(int x0,int y0,int x1,int y1,int color,HDC hdc)
{
    float dy,dx,x,y,m;
    dx=x1-x0;
    dy=y1-y0;
    m=dy/dx;
    if(x0<x1)
    {
        if(m<=1&&m>=-1)
        {
              y=y0;
              for(x=x0;x<=x1;x++)
              {
                  SetPixel(hdc,x,int(y+0.5),color);
                  y+=m;
              }
        }
    }
    if(x0>x1)
    {
        if(m<=1&&m>=-1)
        {
              y=y0;
              for(x=x0;x>=x1;x--)
              {
                  SetPixel(hdc,x,int(y+0.5),color);
                  y-=m;
              }
        }
    }
    if(y0<y1)
    {
        if(m>=1||m<=-1)
        {
              m=1/m;
              x=x0;
              for(y=y0;y<=y1;y++)
              {
                  SetPixel(hdc,int(x+0.5),y,color);
                  x+=m;
              }
        }
    }
    if(y0>y1)
    {
        if(m<=-1||m>=1)
        {
              m=1/m;
              x=x0;
              for(y=y0;y>=y1;y--)
              {
                  SetPixel(hdc,int(x+0.5),y,color);
                  x-=m;
              }
        }
    }
}
//---------------------------------------------------------------------
//DDA算法对应的演示功能函数
//---------------------------------------------------------------------
void LineDDA_Demo(int x0,int y0,int x1,int y1,int color,HDC hdc,bool demo)
{
    float dy,dx,x,y,m,Time;
    Time=timeGetTime();
    dx=x1-x0;
    dy=y1-y0;
    m=dy/dx;
    if(x0<x1)
    {
        if(m<=1&&m>=-1)
        {
              y=y0;
              for(x=x0;x<=x1;x++)
              {
                  BitBlt(hdc,x*10,int(y+0.5)*10,10,10,MemDC,0,0,SRCCOPY);
                  y+=m;
                  if(demo)
                  {
                      while((timeGetTime()-Time)<delay)
                            int a=1;
                  }
                  Time=timeGetTime();
              }
        }
    }
    if(x0>x1)
    {
        if(m<=1&&m>=-1)
        {
              y=y0;
              for(x=x0;x>=x1;x--)
              {
                  BitBlt(hdc,x*10,int(y+0.5)*10,10,10,MemDC,0,0,SRCCOPY);
                  y-=m;
                  if(demo)
                  {
                      while((timeGetTime()-Time)<delay)
                            int a=1;
                  }
                  Time=timeGetTime();
              }
        }
    }
    if(y0<y1)
    {
        if(m>=1||m<=-1)
        {
              m=1/m;
              x=x0;
              for(y=y0;y<=y1;y++)
              {
                  BitBlt(hdc,int(x+0.5)*10,y*10,10,10,MemDC,0,0,SRCCOPY);
                  x+=m;
                  if(demo)
                  {
                      while((timeGetTime()-Time)<delay)
                            int a=1;
                  }
                  Time=timeGetTime();
              }
        }
    }
    if(y0>y1)
    {
        if(m<=-1||m>=1)
        {
              m=1/m;
              x=x0;
              for(y=y0;y>=y1;y--)
              {
                  BitBlt(hdc,int(x+0.5)*10,y*10,10,10,MemDC,0,0,SRCCOPY);
                  x-=m;
                  if(demo)
                  {
                      while((timeGetTime()-Time)<delay)
                            int a=1;
                  }
                  Time=timeGetTime();
              }
        }
    }
}以上代码仅供参考,编程环境VC.NET,希望能给还没有任何思路的同学一点帮助,完整源文件不提供,请勿开口索要。

 

//---------------------------------------------------------------------
//绘制直线的中点算法基本函数
//---------------------------------------------------------------------
void LineMID(int x0,int y0,int x1,int y1,int color,HDC hdc)
{
     float dx,dy,incrE,incrNE,d,x,y,m;
     if(true)
     {
           dx=x1-x0;
           if(x0>x1)
                 dx=-dx;
           dy=y1-y0;
           if(y0>y1)
                 dy=-dy;
           m=dy/dx;
           d=dx-2*dy;
           incrE=-2*dy;
           incrNE=2*(dx-dy);
           x=x0,y=y0;
           SetPixel(hdc,x,y,color);
           if(m<=1&&m>=-1)
           {
                 if(x0<x1)
                 {
                       while(x<x1)
                       {
                             if(d>0)
                                   d+=incrE;
                             else
                             {
                                   d+=incrNE;
                                   y++;
                             }
                             x++;
                             if(y0<y1)
                                   SetPixel(hdc,x,y,color);
                             if(y0>=y1)
                                   SetPixel(hdc,x,(2*y0-y),color);
                       }
                 }
                 if(x0>=x1)
                 {
                       while(x>x1)
                       {
                             if(d>0)
                                   d+=incrE;
                             else
                             {
                                   d+=incrNE;
                                   y++;
                             }
                             x--;
                             if(y0<y1)
                                   SetPixel(hdc,x,y,color);
                             if(y0>=y1)
                                   SetPixel(hdc,x,(2*y0-y),color);
                       }
                 }
           }
           if(m<-1||m>1)
           {
                 dx=x1-x0;
                 if(x0>x1)
                       dx=-dx;
                 dy=y1-y0;
                 if(y0>y1)
                       dy=-dy;
                 d=dy-2*dx;     //与斜率小于1时候的情况相比,dx与dy的值刚好互换
                 incrE=-2*dx;
                 incrNE=2*(dy-dx);
                 x=x0,y=y0;
                 if(y0<y1)
                 {
                       while(y<y1)
                       {
                             if(d>0)
                                   d+=incrE;
                             else
                             {
                                   d+=incrNE;
                                   x++;
                             }
                             y++;
                             if(x0<x1)
                                   SetPixel(hdc,x,y,color);
                             if(x0>=x1)
                                   SetPixel(hdc,(2*x0-x),y,color);
                       }
                 }
                 if(y0>=y1)
                 {
                       while(y>y1)
                       {
                             if(d>0)
                                   d+=incrE;
                             else
                             {
                                   d+=incrNE;
                                   x++;
                             }
                             y--;
                             if(x0<x1)
                                   SetPixel(hdc,x,y,color);
                             if(x0>=x1)
                                   SetPixel(hdc,(2*x0-x),y,color);
                       }
                 }
           }
     }
}
//---------------------------------------------------------------------
//中点算法对应的演示功能函数
//---------------------------------------------------------------------
void LineMID_Demo(int x0,int y0,int x1,int y1,int color,HDC hdc,bool demo)
{
     float dx,dy,incrE,incrNE,d,x,y,m,Time;
     Time=timeGetTime();
     if(true)
     {
           dx=x1-x0;
           if(x0>x1)
                 dx=-dx;
           dy=y1-y0;
           if(y0>y1)
                 dy=-dy;
           m=dy/dx;
           d=dx-2*dy;
           incrE=-2*dy;
           incrNE=2*(dx-dy);
           x=x0,y=y0;
           BitBlt(hdc,x*10,y*10,10,10,MemDC,0,0,SRCCOPY);
           if(m<=1&&m>=-1)
           {
                 if(x0<x1)
                 {
                       while(x<x1)
                       {
                             if(d>0)
                                   d+=incrE;
                             else
                             {
                                   d+=incrNE;
                                   y++;
                             }
                             x++;
                             if(y0<y1)
                                   BitBlt(hdc,x*10,y*10,10,10,MemDC,0,0,SRCCOPY);
                             if(y0>=y1)
                                   BitBlt(hdc,x*10,(2*y0-y)*10,10,10,MemDC,0,0,SRCCOPY);
                             if(demo)
                             {
                                   while((timeGetTime()-Time)<delay)
                                         int a=1;
                             }
                             Time=timeGetTime();
                       }
                 }
                 if(x0>=x1)
                 {
                       while(x>x1)
                       {
                             if(d>0)
                                   d+=incrE;
                             else
                             {
                                   d+=incrNE;
                                   y++;
                             }
                             x--;
                             if(y0<y1)
                                   BitBlt(hdc,x*10,y*10,10,10,MemDC,0,0,SRCCOPY);
                             if(y0>=y1)
                                   BitBlt(hdc,x*10,(2*y0-y)*10,10,10,MemDC,0,0,SRCCOPY);
                             if(demo)
                             {
                                   while((timeGetTime()-Time)<delay)
                                         int a=1;
                             }
                             Time=timeGetTime();
                       }
                 }
           }
           if(m<-1||m>1)
           {
                 dx=x1-x0;
                 if(x0>x1)
                       dx=-dx;
                 dy=y1-y0;
                 if(y0>y1)
                       dy=-dy;
                 d=dy-2*dx;
                 incrE=-2*dx;
                 incrNE=2*(dy-dx);
                 x=x0,y=y0;
                 if(y0<y1)
                 {
                       while(y<y1)
                       {
                             if(d>0)
                                   d+=incrE;
                             else
                             {
                                   d+=incrNE;
                                   x++;
                             }
                             y++;
                             if(x0<x1)
                                   BitBlt(hdc,x*10,y*10,10,10,MemDC,0,0,SRCCOPY);
                             if(x0>=x1)
                                   BitBlt(hdc,(2*x0-x)*10,y*10,10,10,MemDC,0,0,SRCCOPY);
                             if(demo)
                             {
                                   while((timeGetTime()-Time)<delay)
                                         int a=1;
                             }
                             Time=timeGetTime();
                       }
                 }
                 if(y0>=y1)
                 {
                       while(y>y1)
                       {
                             if(d>0)
                                   d+=incrE;
                             else
                             {
                                   d+=incrNE;
                                   x++;
                             }
                             y--;
                             if(x0<x1)
                                   BitBlt(hdc,x*10,y*10,10,10,MemDC,0,0,SRCCOPY);
                             if(x0>=x1)
                                   BitBlt(hdc,(2*x0-x)*10,y*10,10,10,MemDC,0,0,SRCCOPY);
                             if(demo)
                             {
                                   while((timeGetTime()-Time)<delay)
                                         int a=1;
                             }
                             Time=timeGetTime();
                       }
                 }
           }
     }
}

//---------------------------------------------------------------------

 

bresenham算法是计算机图形学中为了“显示器(屏幕或打印机)系由像素构成”的这个特性而设计出来的算法,使得在求直线各点的过程中全部以整数来运算,因而大幅度提升计算速度

Bresenham算法是计算机图形学领域使用最广泛的直线扫描转换方法。原理是:

  过各行、各列像素中心构造一组虚拟网格线,按直线从起点到终点的顺序计算直线各垂直网格线的交点,然后确定该列像素中与此交点最近的像素。该算法的优点在于可以采用增量计算,使得对于每一列,只要检查一个误差项的符号,就可以确定该列所求的像

//绘制直线的Bresenham算法基本函数


//---------------------------------------------------------------------void LineBRE(int x0,int y0,int x1,int y1,int color,HDC hdc)
{
     float dy,dx,x,y,m,d;
     dx=x1-x0;
     if(x1<x0)
           dx=-dx;
     dy=y1-y0;
     if(y1<y0)
           dy=-dy;
     m=dy/dx;
     d=-dx;
     x=x0,y=y0;
     if(x0<x1)
     {
           if(m<=1&&m>=-1)
           {
                 for(x=x0;x<=x1;x++)
                 {
                       if(d>=0)
                       {
                             y++;
                             d-=2*dx;
                       }
                       d+=2*dy;
                       if(y1<y0)
                             SetPixel(hdc,x,(2*y0-y),color);
                       else
                             SetPixel(hdc,x,y,color);
                 }
           }
     }
     if(x0>=x1)
     {
           if(m<=1&&m>=-1)
           {
                 for(x=x0;x>=x1;x--)
                 {
                       if(d>=0)
                       {
                             y++;
                             d-=2*dx;
                       }
                       d+=2*dy;
                       if(y1<y0)
                             SetPixel(hdc,x,(2*y0-y),color);
                       else
                             SetPixel(hdc,x,y,color);
                 }
           }
     }
     if(y0<y1)
     {
           if(m<-1||m>1)
           {
                 for(y=y0;y<=y1;y++)
                 {
                       if(d>=0)
                       {
                             x++;
                             d-=2*dy;
                       }
                       d+=2*dx;
                       if(x1<x0)
                             SetPixel(hdc,(2*x0-x),y,color);
                       else
                             SetPixel(hdc,x,y,color);
                 }
           }
     }
     if(y0>=y1)
     {
           if(m<-1||m>1)
           {
                 for(y=y0;y>=y1;y--)
                 {
                       if(d>=0)
                       {
                             x++;
                             d-=2*dy;
                       }
                       d+=2*dx;
                       if(x1<x0)
                             SetPixel(hdc,(2*x0-x),y,color);
                       else
                             SetPixel(hdc,x,y,color);
                 }
           }
     }
}
//---------------------------------------------------------------------
//Bresenham算法对应的演示功能函数
//---------------------------------------------------------------------
void LineBRE_Demo(int x0,int y0,int x1,int y1,int color,HDC hdc,bool demo)
{
     float dy,dx,x,y,m,d,Time;
     Time=timeGetTime();
     dx=x1-x0;
     if(x1<x0)
           dx=-dx;
     dy=y1-y0;
     if(y1<y0)
           dy=-dy;
     m=dy/dx;
     d=-dx;
     x=x0,y=y0;
     if(x0<x1)
     {
           if(m<=1&&m>=-1)
           {
                 for(x=x0;x<=x1;x++)
                 {
                       if(d>=0)
                       {
                             y++;
                             d-=2*dx;
                       }
                       d+=2*dy;
                       if(y1<y0)
                             BitBlt(hdc,x*10,(2*y0-y)*10,10,10,MemDC,0,0,SRCCOPY);
                       else
                             BitBlt(hdc,x*10,y*10,10,10,MemDC,0,0,SRCCOPY);
                       if(demo)
                       {
                             while((timeGetTime()-Time)<delay)
                                   int a=1;
                       }
                       Time=timeGetTime();
                 }
           }
     }
     if(x0>=x1)
     {
           if(m<=1&&m>=-1)
           {
                 for(x=x0;x>=x1;x--)
                 {
                       if(d>=0)
                       {
                             y++;
                             d-=2*dx;
                       }
                       d+=2*dy;
                       if(y1<y0)
                             BitBlt(hdc,x*10,(2*y0-y)*10,10,10,MemDC,0,0,SRCCOPY);
                       else
                             BitBlt(hdc,x*10,y*10,10,10,MemDC,0,0,SRCCOPY);
                       if(demo)
                       {
                             while((timeGetTime()-Time)<delay)
                                   int a=1;
                       }
                       Time=timeGetTime();
                 }
           }
     }
     if(y0<y1)
     {
           if(m<-1||m>1)
           {
                 for(y=y0;y<=y1;y++)
                 {
                       if(d>=0)
                       {
                             x++;
                             d-=2*dy;
                       }
                       d+=2*dx;
                       if(x1<x0)
                             BitBlt(hdc,(2*x0-x)*10,y*10,10,10,MemDC,0,0,SRCCOPY);
                       else
                             BitBlt(hdc,x*10,y*10,10,10,MemDC,0,0,SRCCOPY);
                       if(demo)
                       {
                             while((timeGetTime()-Time)<delay)
                                   int a=1;
                       }
                       Time=timeGetTime();
                 }
           }
     }
     if(y0>=y1)
     {
           if(m<-1||m>1)
           {
                 for(y=y0;y>=y1;y--)
                 {
                       if(d>=0)
                       {
                             x++;
                             d-=2*dy;
                       }
                       d+=2*dx;
                       if(x1<x0)
                             BitBlt(hdc,(2*x0-x)*10,y*10,10,10,MemDC,0,0,SRCCOPY);
                       else
                             BitBlt(hdc,x*10,y*10,10,10,MemDC,0,0,SRCCOPY);
                       if(demo)
                       {
                             while((timeGetTime()-Time)<delay)
                                   int a=1;
                       }
                       Time=timeGetTime();
                 }
           }
     }
}

 

 

转自:http://lehuabupt.bokee.com/viewdiary.13365101.html

 

原创粉丝点击