基本图形的生成:DDA,中点算法生成直线

来源:互联网 时间:1970-01-01

数学上,理想的直线是由无数个点构成的集合,没有宽度。计算机绘制直线是在显示器所给定的有限个像素组成的矩阵中,确定最佳逼近该直线的一组像素,并且按扫描线顺序,对这些像素进行写操作,实现显示器绘制直线,即通常所用说直线的扫描转换,或称直线光栅化.

1.DDA 算法原理
知端点p0,p1,得知斜率,从端点步进画线,步长1像素,注意斜率大于小于1的区别

 1: //点击"DDA算法生成直线"消息处理函数-使用DDA算法画一条直线
 2: void CMyView::OnDdaline()
 3: {
 4: // TODO: Add your command handler code here
 5: CDC* pDC=GetDC();//获得设备指针
 6: int xa=100, ya=300, xb=300, yb=200,c=RGB(0,0,0);//定义直线的两端点,直线颜色
 7: int x,y; 
 8: float dx, dy, k; 
 9: dx=(float)(xb-xa), dy=(float)(yb-ya); 
 10: k=dy/dx, y=ya,x=xa; //直线斜率
 11: if(abs(k)>=0)
 12: {//以xa,ya为端点,从端点步进画线,步长1像素
 13: for (x=xa;x<=xb;x++) 
 14: {pDC->SetPixel (x,int(y+k),c); 
 15: y=(int)(y+k);}
 16: }
 17: if(abs(k)>=1)
 18: {
 19: for (y=ya;y<=yb;y++) 
 20: {pDC->SetPixel (int(x+0.5),y,c);
 21: x=(int)(x+1/k);
 22: } 
 23: }
 24: ReleaseDC(pDC);
 25: }

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: } 

书上代码为:

 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: } 
把 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为下一个像素;


相关阅读:
Top