您的位置:首页 > 其它

DDA,中点算法生成直线

2011-07-01 23:27 405 查看
数学上,理想的直线是由无数个点构成的集合,没有宽度。计算机绘制直线是在显示器所给定的有限个像素组成的矩阵中,确定最佳逼近该直线的一组像素,并且按扫描线顺序,对这些像素进行写操作,实现显示器绘制直线,即通常所用说直线的扫描转换,或称直线光栅化.
1.DDA 算法原理
知端点p0,p1,得知斜率,从端点步进画线,步长1像素,注意斜率大于小于1的区别
//点击"DDA算法生成直线"消息处理函数-使用DDA算法画一条直线
void CMyView::OnDdaline()
{
// TODO: Add your command handler code here
CDC* pDC=GetDC();//获得设备指针
int xa=100, ya=300, xb=300, yb=200,c=RGB(0,0,0);//定义直线的两端点,直线颜色
int x,y;
float dx, dy, k;
dx=(float)(xb-xa), dy=(float)(yb-ya);
k=dy/dx, y=ya,x=xa; //直线斜率
if(abs(k)>=0)
{//以xa,ya为端点,从端点步进画线,步长1像素
for (x=xa;x<=xb;x++)
{pDC->SetPixel (x,int(y+k),c);
y=(int)(y+k);}
}
if(abs(k)>=1)
{
for (y=ya;y<=yb;y++)
{pDC->SetPixel (int(x+0.5),y,c);
x=(int)(x+1/k);
}
}
ReleaseDC(pDC);
}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

2.中点画线法

当前像素点为 p,下一个像素点有两种选择,点 p1或 p2.M为p1与p2中点,Q 为理想直线与x=xp+1垂线的交点,当M在Q的下方,则P2应为下一个像素点;M在 Q 的上方,应取P1为下一点.

生成直线的重点划线法:M在Q下方,取上方点;M在Q上方,取下方候选点. F(x,y)=ax+by+c=0. a=y0-y1,b=x1-x0,c=x0y1-x1y0;

自己理解之后写出:

1: void CMyView::OnMline()

2: {

3: CDC *pDC=GetDC();//获得设备指针

4: int x0=100,y0=300,x1=300,y1=200,c=RGB(0,0,0);//线段端点

5: float a=(float)(y0-y1),b=(float)(x1-x0);//以直线函数为F(x,y)=ax+by+c=0

6: float k=(-1)*(a/b);//斜率

7: int x=x0,y=y0;//直线当前点初始位置x,y

8: //开始逐步步进 1像素画点

9: while(x<=x1)

10: {

11: float xp=(float)(x+1),yp=(float)(y+(-1)*(a/b));//步进 1像素之后理想点初始位置

12: float xm=(float)(x+1),ym=(float)((int)yp+0.5);//中点初始位置

13: int delt=yp-ym;//理想位置-中点位置 差值

14: pDC->SetPixel(x,y,c);

15: if(delt>0)

16: {

17: x++;

18: y=y+(-1)*(a/b)+1;

19: }

20: else if(delt<=0)

21: {

22: x++;

23: y=y+(-1)*(a/b);

24: }

25: }

26: ReleaseDC(pDC);

27: }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

书上代码为:

1: void CMyView::OnMline()

2: {

3: // TODO: Add your command handler code here

4: CDC* pDC=GetDC();

5: int xa=300, ya=200, xb=450, yb=300,c=RGB(0,255,0);

6: float a, b, d1, d2, d, x, y;

7: a=ya-yb, b=xb-xa, d=2*a+b;

8: d1=2*a, d2=2* (a+b);

9: x=xa, y=ya;

10: pDC->SetPixel(x, y, c);

11: while (x<xb)

12: { if (d<0) {x++, y++, d+=d2; }

13: else {x++, d+=d1;}

14: pDC->SetPixel(x, y, c);

15: }

16: ReleaseDC(pDC);

17: }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

把 M 代入 F(x,y)判断 F 的符号,可知 Q 点在中点 M 的上方还是下 方。
为此构造判别式:d=F(M)=F(xp+1, yp+0.5)=a(xp+1)+b(yp+0.5)+c
当 d<0,L(Q 点) 在 M 上方,取 P2为下一个像素;
当 d>0,L(Q 点)在 M 下方,取 P1为下一个像素;
当 d=0,选 P1或 P2均可,取 P1为下一个像素;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: