CDC *pdc = CDC::FromHandle(hdc)
pdc->MoveTo(ps)
pdc->竖春渗LineTo(pe)
以下是引用:
直线段的扫描转换算法
1 数值微分(DDA)法
我的理解就是以一个坐标轴为步长值(增量为1),另一个坐标根据直线的斜率(K)为
增量,然后四舍五入进行余脊计算机,确定每一个点的坐标。
具体算法(我用OPENGL模拟)
void setPixel(GLint xCoord,GLint yCoord)
{
glBegin(GL_POINTS)
glVertex2i(xCoord,yCoord)
glEnd()
}
inline int round(const float a)
{
return int(a+0.5)
}
void lineDDA(int x0,int y0,int xEnd,int yEnd)
{
int dx = xEnd - x0,dy = yEnd - y0,steps,k
float xIncrement,yIncrement,x = x0,y=y0
if(abs(dx)>abs(dy))
{
steps = abs(dx)
}
else
{
steps = abs(dy)
}
xIncrement = float(dx)/float(steps)
yIncrement = float(dy)/float(steps)
setPixel(round(x),round(y))
for(k = 0k<stepsk++)
{
x+=xIncrement
y+=yIncrement
setPixel(round(x),round(y))
}
}
2中点画线法
同样我理解的算法就是,以一个增量为多的坐标轴为步长值(为1),而另一个坐标
值是加1,还是不变取决于这两个坐标值中点是在这条直线的上方,还是下方。
具体算法如下:
void lineMiddle(int x0,int y0,int xEnd,int yEnd)
{
int a,b,c,d1,d2,d
a = y0-yEnd
b = xEnd-x0
d = 2*a+b//判别试(2a+b为初始值)
d1 = 2*a//中点在直线下方增量值
d2 = 2*a+b//中点在真线上方的增量值
int x,y
x = x0y=y0
setPixel(x,y)
while(x<xEnd)
{
if(d<0)//中点在直线下方
{
x++
y++
d+=d2
}
else//中点在直线上方
{
x++
d+=d1
}
setPixel(x,y)
}
}
3.Bresenham画线算法程序:
用一个坐标轴来当步长值(即+1),另一个坐标轴是否加1则跟据斜率(k)来确定森烂,K
如果大于0.5,那么也加+1,如果小于0.5那么即不变。为了方便计算,如果d大于1
,那么就减一,归0。可设e,e=d-0.5,于是就有e>0时,加1,e<0时不变,这样便
于硬件实现。
算法实现如下:
void lineBresenham(int x0,int y0,int x1,int y1)
{
int x,y,dx,dy
float k,e
dx = x1 - x0
dy = y1 - y0
k = (float)dy/dx
e = -0.5
x = x0
y = y0
setPixel(x,y)
for(int i =0i<dxi++)
{
x = x+1
e = e+k
if(e>=0)
{
y++
e = e-1
}
setPixel(x,y)
}
}
直线方程:a*x+b*y+c=0, p1(x1,y1), p2(x2,y2)==>a=y1-y2b=x2-x1.点到直线的距离:拆陆敬distance=|a*x0-b*y0+c|/sqrt(a*a + b*b)
设directionX,directionY分别为从(x1,y1)==>(x2,y2)的单位变化量(+/-1)
当直线偏向X轴时,当前象素为(xk, yk),下一个象素可能为:(xk+directionX, yk)或者(xk+directionX,yk+directionY)这两点到直线的距离分别为:
d1=|a*xk+b*yk+c+a*directionX|/sqrt(a*a + b*b)
d2=|a*xk+b*yk+c+a*directionX+b*directonY|/sqrt(a*a + b*b)
便于运算,定义:f(xk,yk)= d2 * d2 - d1 * d1 (将d1和d2的分母去掉了的)
= b*b + 2*b*directonY*(a*xk+b*yk+c+a*directionX)
当f(xk,yk)<0的时候,下一个点为(xk+directionX,yk+directionY):
f(xk+directionX,yk+directionY)=f(xk,yk) +2*b*b+2*a*b*directionX*directionY
当f(xk,yk)>=0的时候,下一旅慎个点为(xk+directionX, yk) :
f(xk+directionX, yk) = f(xk,yk) + 2*a*b*directionX*directionY
当直线偏向Y轴时,当前象素为(xk, yk),下一个象素可能为:(xk, yk+directionY)或者(xk+directionX,yk+directionY)这两点到直线的距离分别为:
d1=|a*xk+b*yk+c+b*directionY|/悉皮sqrt(a*a + b*b)
d2=|a*xk+b*yk+c+b*directionY+a*directonX|/sqrt(a*a + b*b)
便于运算,定义:f(xk,yk)= d2 * d2 - d1 * d1 (将d1和d2的分母去掉了的)
= a*a + 2*a*directonX*(a*xk+b*yk+c+b*directionY)
当f(xk,yk)<0的时候,下一个点为(xk+directionX,yk+directionY):
f(xk+directionX,yk+directionY)=f(xk,yk) +2*a*a+2*a*b*directionX*directionY
当f(xk,yk)>=0的时候,下一个点为(xk+directionX, yk) :
f(xk+directionX, yk) = f(xk,yk) + 2*a*b*directionX*directionY
/*
* 中点画线算法
*/
void LineMLDA(HDC&hdc, POINT ptSrc, POINT ptDec, COLORREF cr)
{
int a, b
a = ptSrc.y - ptDec.y
b = ptDec.x - ptSrc.x
int iDirectionX, iDirectionY
iDirectionX = iDirectionY = 1
if(b<0)
iDirectionX = -1
if(a>0)
iDirectionY = -1
int iDistance,
iDeltaSmall, iDeltaBig ,
iCurrX, iCurrY
int iStep
iDeltaSmall = 2*a*b*iDirectionX*iDirectionY
iCurrX = ptSrc.x
iCurrY = ptSrc.y
if(abs(b) >abs(a))
{
iDeltaBig = 2*b*b + iDeltaSmall
iDistance = b*b + iDeltaSmall
iStep = abs(b)
while (iStep-- >0)
{
SetPixel(hdc, iCurrX, iCurrY, cr)
iCurrX += iDirectionX
if(iDistance <0)
{
iCurrY+= iDirectionY
iDistance += iDeltaBig
}
else
{
iDistance += iDeltaSmall
}
}
}
else
{
iDeltaBig = 2*a*a + iDeltaSmall
iDistance = a*a + iDeltaSmall
iStep = abs(a)
while (iStep-- >0)
{
SetPixel(hdc, iCurrX, iCurrY, cr)
iCurrY += iDirectionY
if(iDistance <0)
{
iCurrX+= iDirectionX
iDistance += iDeltaBig
}
else
{
iDistance += iDeltaSmall
}
}
}
SetPixel(hdc, ptDec.x, ptDec.y, cr)
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)