路径画刷的使用及其应用场合

链接:路径画刷的使用及其应用场合思考

   
  计算机图形学的一大目的是为了更好地模拟世界,而且这种模拟的准确度以还原事物的本来面目的程度来衡量。之前我们学习了GDI+中的线性画刷(如果你不知道,这里告诉你如何使用:GDI+学习之线性渐变画刷)。线性渐变画刷中控制画刷变化的实质上那条虚拟的渐变线。我们知道事物的变化规律并不限于变化的,而且常常不是线性变化的。现在开始学习模拟事物的非线性变化的GDI+的路径画刷。路径画刷的最基本用法非常简单:定义一个路径,再定义一个路径画刷绑定这个路径,然后设置中心点颜色和边界点颜色,最后使用这个画刷填充这个路径。下面是一个使用例子:

 

C/C++ code
   
   
CDC * pDC = pView -> GetDC(); Graphics gp(pDC -> m_hDC); Point points[] = { Point( 175 , 0 ),Point( 200 , 50 ),Point( 250 , 50 ),Point( 212 , 75 ),Point( 250 , 150 ),Point( 175 , 100 ), Point( 100 , 150 ),Point( 137 , 75 ),Point( 100 , 50 ),Point( 150 , 50 )}; // define the changing path GraphicsPath path; path.AddLines(points, 10 ); PathGradientBrush pthGrBrush( & path); pthGrBrush.SetCenterColor(Color( 255 , 255 , 0 , 0 )); Color colors[] = {Color( 255 , 0 , 0 , 0 ),Color( 255 , 0 , 255 , 0 ),Color( 255 , 0 , 0 , 255 ),Color( 255 , 255 , 255 , 255 ), Color( 255 , 0 , 0 , 0 ),Color( 255 , 255 , 255 , 255 ),Color( 255 , 0 , 0 , 255 ),Color( 255 , 255 , 255 , 255 ), Color( 255 , 0 , 0 , 0 ),Color( 255 , 0 , 255 , 0 )}; int count = 10 ; pthGrBrush.SetSurroundColors(colors, & count); gp.FillPath( & pthGrBrush, & path); SolidBrush blackbrush(Color::Black); for ( int i = 0 ;i < 10 ;i ++ ) { gp.FillEllipse( & blackbrush,points[i].X - 5 ,points[i].Y - 5 , 10 , 10 ); } gp.ReleaseHDC(pDC -> m_hDC); pView -> ReleaseDC(pDC);



  效果图如下:


   
  同线性渐变画刷相比,路径渐变画刷的最大特点在于:路径渐变画刷的渐变方向是从路径中央到路径边缘,是一种呈发散状的渐变,而线性渐变画刷的渐变方向较为单一(水平、垂直、固定角度)。所以,在使用路径渐变画刷填充目标区域之前,除了需要指定路径对象外,还要指定路径的中心点色彩(起点色)和路径的边界色彩(终点色)。

  那么路径画刷可以模拟哪些场合呢?我们知道模拟常常是通过一些离散的数据来模拟连续的场景。我们假设下面有这样一个场景:有四个离散点,它们的属性值分别是0,80,320,160,它们分别有对应的RGB颜色,如下图所示:

 

  
  那我们如何模拟由端点1234组成的多边形的内部的属性值的变化呢。在这种使用线性渐变画刷是做不到的,我想一种做法是假设该多边形的中心为这四个点的属性值的中值,然后根据属性值求取对应的颜色(一般根据一个属性值都能求取到一个对应颜色),然后把它设为中心点颜色,1234四个端点设为边界点,采用路径画刷进行绘图。我想这个不失为一个模拟办法。
下面是示例代码:
 

C/C++ code
   
   
CDC * pDC = pView -> GetDC(); Graphics gp(pDC -> m_hDC); Pen blackPen(Color::Black, 1 ); Point points[] = { Point( 200 , 0 ),Point( 100 , 80 ),Point( 200 , 320 ),Point( 300 , 160 )}; for ( int i = 0 ;i < 4 - 1 ;i ++ ) gp.DrawLine( & blackPen,points[i],points[i + 1 ]); gp.DrawLine( & blackPen,points[ 0 ],points[ 3 ]); SolidBrush blackBrush(Color::Black); Gdiplus::FontFamily fontfm(L " 宋体 " ); Gdiplus::Font font( & fontfm, 24 ,Gdiplus::FontStyleRegular,Gdiplus::UnitPixel); WCHAR buffer[ 200 ]; for ( int i = 0 ;i < 4 ;i ++ ) { gp.FillEllipse( & blackBrush,points[i].X - 2 ,points[i].Y - 2 , 4 , 4 ); swprintf_s(buffer, 200 ,L " %d " ,i + 1 ); if (i < 2 ) { PointF pt(points[i].X - 30 ,points[i].Y); gp.DrawString(buffer, - 1 , & font,pt, & blackBrush); } else { PointF pt(points[i].X,points[i].Y); gp.DrawString(buffer, - 1 , & font,pt, & blackBrush); } } Color colors[] = {Color( 255 , 0 , 0 , 125 ),Color( 255 , 0 , 0 , 255 ),Color( 255 , 0 , 255 , 0 ),Color( 255 , 255 , 0 , 0 )}; for ( int i = 0 ;i < 4 ;i ++ ) { swprintf_s(buffer, 200 ,L " %d " ,i + 1 ); PointF pt( 500.0 ,(i + 1 ) * 50.0 ); gp.DrawString(buffer, - 1 , & font,pt, & blackBrush); Pen labelPen(colors[i], 1.0f ); gp.DrawLine( & labelPen,Point( 550 ,(i + 1 ) * 50 ),Point( 650 ,(i + 1 ) * 50 )); } GraphicsPath path; path.AddLines(points, 4 ); PathGradientBrush pthGrBrush( & path); /* 这里暂假设中心点的属性值的对应的颜色为Color(255,125,125,125),在实际中要根据属性值求取 */ pthGrBrush.SetCenterColor(Color( 255 , 125 , 125 , 125 )); int count = 4 ; pthGrBrush.SetSurroundColors(colors, & count); gp.FillPath( & pthGrBrush, & path); gp.ReleaseHDC(pDC -> m_hDC); pView -> ReleaseDC(pDC);


 
  效果图如下:
 

   
当然我想也可以把四个点划分为124和234两个三角形,然后分别对这两个三角形使用路径画刷填充。我估计在某些情况下这种模拟更为准确。

思考题:

  在osg中可以使用一个端点绑定一种颜色的做法来绘制一个颜色渐变的多边形,你知道其中的颜色渐变原理吗?使用GDI+如何模拟osg的这种渐变呢?

参考文献:

1.《精通GDI+编程》,周名扬、赵景亮编著。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值