AGG 顶点源(Vertex Source)


顶点源(Vertex Source)

 

                                                                         原帖地址:http://hi.baidu.com/%E5%D4%E5%C6%B6%C0%D0%D0/blog/item/d0c8293ac9ed78ffb311c736.html

顶点源是一种可以产生多边形所需要的“带命令的顶点”的对象。比如三角形顶点源,就应该会产生一个带“MoveTo”命令的点,另外二 个带"LineTo"命令的点和最终闭合的“ClosePoly”命令。

头文件
#include <agg_path_storage.h> //path_storage

#include <agg_ellipse.h> // ellipse
#include <agg_arc.h> // arc
#include <agg_arrowhead.h> // arrowhead
#include <agg_curves.h> // curve3, curve4
#include <agg_gsv_text.h> // gsv_text, gsv_text_outline
#include <agg_rounded_rect.h> // rounded_rect
...
类型
自定义类所有实现了void rewind(unsigned path_id);和unsigned vertex(double* x, double* y);的类。
ellipse圆,输入为中心点坐标和XY轴半径,本文所用的例子 就 使用了这个顶点源
arc弧线,输入为中心点坐标和XY轴半径,以及起始和终止角(rad),顺时针/逆时针方向
curve3贝塞尔曲线,输入为起点坐标、第一控制点坐标、终点点坐标
curve4贝塞尔曲线,输入为起点坐标、第一控制点坐标、第二控制点坐标、终点坐标
gsv_text使用AGG自带字模的文字输出(只支持ASCII码),使用start_point方法指定文字位置,text方法指定 文字,flip指定是否上下倒转,size指定文字大小,适合与conv_stroke或gsv_text_outline配合。
gsv_text_outline<>可变换文字,输入为gsv_text和变换矩阵(默认为trans_affine,后文会提到)。width方法设置文 字宽度
rounded_rect圆角方形,输入为左上角右下角坐标和圆角半径
path_storage路径存储器,可以用join_path方法加入多个顶点源。而且path_storage本身支持move_to, line_to,curve和arc_to等画线功能
arrowhead箭头,它是作为标记点来用的

其中的arrowhead颇为特殊,它一般作为线段的标记点,具体用法是这样的:

arrowhead ah;
ah.head(d1,d2,d3,d4); //定义箭头
ah.tail(d1,d2,d3,d4); //定义箭尾
VertexSource VS; //其它顶点源
// 使用顶点转换器,并指定Markers类型为vcgen_markers_term
// 顶点转换器可以是conv_dash、conv_stroke或conv_marker_adaptor,见后文《坐标转换管道》
// vcgen_markers_term:以端点作为标记点
conv_stroke<VertexSource, vcgen_markers_term> csVS(VS);
...draw_term
// 用conv_marker指定ah作为线段marker点的标记
conv_marker<vcgen_markers_term, arrowhead> arrow(csVS.markers(), ah);
ras.add_path(csVS);
ras.add_path(arrow); //marker要紧随其后加入
...render

ah.head()和ah.tail()方法中的d1,d2,d3,d4参数的意义见下图

arrowhead

例,画一条简单的箭头直线(基于此处代码 )

在on_draw()方法最后加上下列代码:

  1. agg::arrowhead ah;
  2. ah.head(0,10,5,5);
  3. ah.tail(10,10,5,5);
  4. // 用path_storage生成一条直线
  5. agg::path_storage ps;
  6. ps.move_to(160,60);
  7. ps.line_to(100,100);
  8. // 转换
  9. agg::conv_stroke<agg::path_storage, agg::vcgen_markers_term> csps(ps);
  10. agg::conv_marker<agg::vcgen_markers_term, agg::arrowhead>
  11.       arrow(csps.markers(), ah);
  12. // 画线
  13. ras.add_path(csps);
  14. agg::render_scanlines_aa_solid(ras,sl,renb,agg::rgba8(0,0,0));
  15. // 画箭头
  16. ras.add_path(arrow);
  17. agg::render_scanlines_aa_solid(ras,sl,renb,agg::rgba8(255,0,0));
得到的图形是:

arrow demo

注意要加头文件:

#include "agg_conv_marker.h"

#include "agg_arrowhead.h"
#include "agg_path_storage.h"
#include "agg_vcgen_markers_term.h"
试验代码,自定义一个顶点源(基于此处代码 )

为了对顶点源有更深入的了解,我们要自己实现一个顶点源,这个顶点源只是很简单的一个三角形。

前面说过,只要实现了 void rewind(unsigned path_id); 和 unsigned vertex(double * x, double * y); 方法就可以作为顶点源。

rewind 方 法指示顶点源回到第一个顶点;vertex 方 法取出当前顶点然后把当前顶点下移,返回值是当前顶点所带的命令。所谓的命令是一个enum path_commands_e 类 型,定义如下:

  1. enum path_commands_e
  2. {
  3.      path_cmd_stop      = 0,        //----path_cmd_stop   
  4.      path_cmd_move_to   = 1,        //----path_cmd_move_to
  5.      path_cmd_line_to   = 2,        //----path_cmd_line_to
  6.      path_cmd_curve3    = 3,        //----path_cmd_curve3
  7.      path_cmd_curve4    = 4,        //----path_cmd_curve4
  8.      path_cmd_curveN    = 5,        //----path_cmd_curveN
  9.      path_cmd_catrom    = 6,        //----path_cmd_catrom
  10.      path_cmd_ubspline = 7,        //----path_cmd_ubspline
  11.      path_cmd_end_poly = 0x0F,     //----path_cmd_end_poly
  12.      path_cmd_mask      = 0x0F      //----path_cmd_mask   
  13. };

path_commands_e 还 能和path_flags_e 组 合:

  1. enum path_flags_e
  2. {
  3.      path_flags_none   = 0,         //----path_flags_none
  4.      path_flags_ccw    = 0x10,      //----path_flags_ccw
  5.      path_flags_cw     = 0x20,      //----path_flags_cw  
  6.      path_flags_close = 0x40,      //----path_flags_close
  7.      path_flags_mask   = 0xF0       //----path_flags_mask
  8. };

vertex()返回的命令中含有path_cmd_stop 时 表示结束。

  1. // 等边三角形
  2. class triangle{
  3. public :
  4.      triangle(double cx, double cy, double r) //中心点,r为中心点到边的长度
  5.      {
  6.         // 直接准备好三个点
  7.          m_step = 0;
  8.          m_pt[0].x = cx; m_pt[0].y = cy-r;
  9.          m_pt[1].x = cx+r*0.866; m_pt[1].y = cy+r*0.5;
  10.          m_pt[2].x = cx-r*0.866; m_pt[2].y = cy+r*0.5;
  11.         //AGG把方向作为区分多边形内部和外部的依据,可以试试m_pt[1]和m_pt[2]对调
  12.      }
  13.     void rewind(unsigned)
  14.      {
  15.          m_step = 0;
  16.      }
  17.      unsigned vertex(double * x, double * y)
  18.      {
  19.         switch (m_step++)
  20.          {
  21.         case 0:
  22.             //第一步,move_to
  23.              *x = m_pt[0].x;
  24.              *y = m_pt[0].y;
  25.             return agg::path_cmd_move_to;
  26.         case 1:
  27.         case 2:
  28.             //第二、三步,line_to
  29.              *x = m_pt[m_step-1].x;
  30.              *y = m_pt[m_step-1].y;
  31.             return agg::path_cmd_line_to;
  32.         case 3:
  33.             // 第四步,闭合多边形
  34.             return agg::path_cmd_end_poly|agg::path_flags_close;
  35.         default :
  36.             // 第五步,结束
  37.             return agg::path_cmd_stop;
  38.          }
  39.      }
  40. private :
  41.      agg::point_d m_pt[3];
  42.      unsigned m_step;
  43. };

在on_draw()方法里把

    agg::ellipse ell(100,100,50,50 ); 改成triangle ell(100,100,50);
    typedef agg::conv_contour<agg::ellipse > ell_cc_type;改成typedef agg::conv_contour<triangle > ell_cc_type;

得到的图形是:

triangle demo

除了文字输出功能(gsv_text只能输出ASCII文字 ),上面这些顶点源提供的图形丰富程度已经超过了系统API。文字输出功能 将以单独的篇幅讲述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值