您的位置:首页 > 理论基础

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

2010-10-15 09:36 267 查看

计算机图形学: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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: