一些常规形几何形状的绘制和效果填充(一)
一些常规形几何形状的绘制和效果填充
常规几何形状是指三角形,多边形,圆,圆弧,直线,点,文字等的绘制。这些基本几何形状经过组合可以形成各种效果图,包括一些仪表和图表。要实现这些效果,使用opengl是最佳选择。但是对于不熟悉opengl编程的人来说,有些困难,而且学习opengl不是几天的事情,而且opengl使用要遵守一定的编程规则,比较繁琐。
本人以CDC类的成员函数为基础,经过几天探索和研究以及综合一些前人代码,完成了一个基本几何图形绘制和效果填充的类CShape.现在介绍给大家。下面图形是示例程序时钟和旋转文字运行截图:
效果图片1:
效果图片2:
CDC类所提供的路径操作和画刷填充是实现这些效果的关键。要实现的具体图形绘制有三种:1.几何轮廓绘制。2.单色几何图形的填充。3.颜色渐变填充。
几何图形轮廓绘制较简单,它的颜色靠传递的pDC的pen决定,靠MoveTO,LineTo绘制直线,靠Arcd等绘制圆弧。关键在于正确计算各个点的位置。在绘图前创建CPen并正确传递给pDC。单色填充使用路径操作来实现。比如要绘制一个单色三角形,具体步骤为:
1. 根据需要生成指定颜色的画刷或者是位图画刷,并正确传递给pDC。
2. 使用路径画三角形并填充:
pDC->BeginPath();//开始定义路径
pDC->MoveTo(p1);//三点定义三角形
pDC->LineTo(p2);
pDC->LineTo(p3);
pDC->LineTo(p1);
pDC->EndPath();//结束,路径一定要封闭
pDC->FillPath();//使用当前画刷填充三角形
对于其他图形比如多边形,一定角度的圆环等几何形状,其绘制关键在于确定形成几何图形的参数个数,然后正确计算各个点的数值,然后BeginPath()和EndPath()创建路径。之后用指定画刷填充FillPath()。对于矩形和圆可以直接用CDC的rectangle和ellipse来绘制填充。但是复杂图形就必须用路径来绘制了。
CDC可以实现单色填充和位图填充,但是不提供颜色渐变。要实现渐变,我目前所知道的方法有两种:
1.用位图填充。
2.使用window API函数GradientFill实现矩形和三角形的渐变填充。
具体介绍如下。
位图填充是指先在内存中绘制一幅覆盖目标区域的位图,然后形成位图画刷进行填充。具体步骤为:
方法1.直接绘制填充位图
CDC* pDC=GetDC();
CBitmap bt,*oldbt;
CDC meDC;
bt.CreateCompatibleBitmap(pDC, R.Width(), R.Height());
//生成空间的//内存位图
meDC.CreateCompatibleDC(pDC);//生成内存DC
oldbt=meDC.SelectObject(&bt);
////////形成需要的位图,包括颜色渐变等
CBrush *old,b(RGB(0,255,0));
old=meDC.SelectObject(&b);
meDC.FillRect(R,&b);
meDC.SelectObject(old);
b.DeleteObject();
/////////////////////////////////////////////////////////
b.CreatePatternBrush(&bt);//形成位图画刷
old=pDC->SelectObject(&b);//载入
pDC->FillRect(R,&b);//使用位图画刷填充图形
pDC->SelectObject(old);
方法2.直接载入位图作为画刷:
CBitmap bt,*oldbt;
bt.LoadBitmap(IDB_BITMAP1);//载入位图
CRect R;
GetClientRect(R);
CBrush *old,b;
b.CreatePatternBrush(&bt);//形成位图画刷
old=pDC->SelectObject(&b);
pDC->FillRect(R,&b);
pDC->SelectObject(old);
bt.DeleteObject();
填充位图
填充效果
另外一种方法是用GradientFill实现渐变填充,参考了一些网上的代码和文献,现在就GradientFill的使用总结如下:
1. 生成全局变量
typedef UINT (CALLBACK* LPFNDLLFUNC1)(HDC,CONST PTRIVERTEX,DWORD,CONST PVOID,DWORD,DWORD);
LPFNDLLFUNC1 handle_GradientFill;
HINSTANCE hinst_msimg32;
bool m_bGradientFillInit;
在初始化时载入动态链接库:msimg32.dll
m_bGradientFillInit=false;
hinst_msimg32=NULL;
hinst_msimg32 = LoadLibrary( "msimg32.dll" );
if(hinst_msimg32)
{
m_bGradientFillInit = TRUE;
handle_GradientFill = ((LPFNDLLFUNC1) GetProcAddress(
hinst_msimg32, "GradientFill" ));
}
2.在程序结束时释放动态链接库:
i f (m_bGradientFillInit)
{
FreeLibrary( hinst_msimg32 );
}
2. 可利用GradientFill实现的填充图形有两种:三角形和矩形。三角形的效果是指定三个点的颜色,然后实现颜色渐变。矩形有两种效果:从左到右实现颜色渐变和从上倒下实现颜色渐变。经过适当的扩展,我增加了三种效果:中心大左右,中心到上下,以及中心到四周的填充效果。具体做法是将矩形分成若干个三角形或矩形,然后分别填充即可实现不同的填充效果。比如中心到左右的填充效果实现如下:先把矩形分成左右两个矩形,对左边矩形实现从左到右的填充,对右边矩形实现从右向左的填充,如此总体效果是从中心到两边的渐变效果。