根据两点画出直线,c++ windows编程 函数。帮忙实现

根据两点画出直线,c++ windows编程 函数。帮忙实现,第1张

CDC类不是有现成的函数么?

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)

}


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/12556229.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-26
下一篇 2023-05-26

发表评论

登录后才能评论

评论列表(0条)

保存