直线图形
绘制直线段一般需要进行栅格化(又叫光栅化)处理:将几何数据经过一系列变换后转换为像素呈现在显示设备上。
数值微分算法(DDA)
数值微分算法本质为用数值方法解微分方程,即通过同时对x和y个增加一个小增量,计算下一步的x,y的值。
DDA的推导公式
DDA画线程序设计
void Line_DDA (CDC *pDC,int xs,int ys,int xe,int ye, COLORREF color) { int t; float x,y,k=(float)(ye-ys)/(xe-xs); if( fbs(k) < 1){ if(xe<xs){ t=xe,xe=xs,xs=t,t=ye,ye=ys,ys=t; } y=ys; for(x=xs;x<=xe;x++) pDC->SetPixel(x,y,color), y=y+k; }else{ if(ye<ys){ t=xe,xe=xs,xs=t,t=ye,ye=ys,ys=t; } x=xs; for(y=ys;y<=ye;y++) pDC->SetPixel(x,y,color),x=x+1/k; } }
|
控制线型的程序设计思路
反走样处理
用离散量表示连续量引起的图形失真,叫走样;减少走样现象的技术和方法称为反走样。
反走样处理:
中点画线法
基本原理
中点法的递推公式
任意方向上的中点法
中点法程序设计
直线段的线宽处理


1) 垂直线刷子:适用于直线斜率在[-1, 1]之间。把线刷子放置成垂直方向,刷子中点对准直线 一端点,然后让刷子中心往直线的另一端移动,即可“刷出”具有一定宽度的线段。
CDC *pDC=GetDC(); dx=xe-xs; dy=ye-ys; e=-dx; y=ys; dxx=dx+dx; dyy=dy+dy; for(x=xs;x<=xe;x++){ pDC->SetPixel(x,y,RGB(0,0,0)); pDC->SetPixel(x-1,y,RGB(0,0,0)); pDC->SetPixel(x+1,y,RGB(0,0,0)); if(e>=0) y=y++, e=e-dxx; e=e+dyy; }
|
2) 水平线刷子:适用于直线斜率不在[1, 1]之间。把线刷子放置成水平方向,刷子中点对准直 线一端点并往直线的另一端移动,可“刷出”具有一定宽度的线。
3)方形刷子:把正方形(边宽为指定线宽)的中心沿直线做平行移动,即可获得具有线宽的线条。
圆与椭圆图形
简单方程产生园弧

绘制圆函数的程序设计
void Arc_Para(CDC *pDC,int xc,int yc,int r,COLORREF color) { int x,y;float d=1/(2*3.14*r); for(float t=0;t<6.283;t=t+d) { x=x0+r*cos(t); y=y0+r*sin(t); pDC->SetPixel (x,y,color); } }
|
中点画圆算法
基本原理
程序设计:
void Circle_DDA(CDC *pDC,int x0,int y0,int r,COLORREF color) { int x=0, y=r, d=1-r; while( y>=x ){ pDC->SetPixel (x+x0,y+y0,color); pDC->SetPixel (-x+x0,y+y0,color); pDC->SetPixel (-x+x0,-y+y0,color); pDC->SetPixel (x+x0,-y+y0,color); pDC->SetPixel (y+x0,x+y0,color); pDC->SetPixel (-y+x0,x+y0,color); pDC->SetPixel (-y+x0,-x+y0,color); pDC->SetPixel (y+x0,-x+y0,color); if(d<0) d=d+2*x+3; else d=d+2*(x-y)+5, y--; x++; } }
|
线宽处理

void Circle_W (CDC *pDC,int x0,int y0,int r,COLORREF color, int w) { int x,y; float d=1/(2*r*3.14); for(float t=0;t<6.3;t=t+d){ x=x0+r*cos(t); y=y0+r*sin(t); float dt=1.0/(3.14*w); for(float t=0;t<6.3;t=t+dt){ xx=x+w/2*cos(t); yy=y+w/2*cos(t); pDC->SetPixel(xx,yy,color); } } }
|