Coordinate conversion pipeline 坐标转换管道
坐标转换管道用于改变顶点源产生的顶点,包括坐标、命令、产生新顶点等。如对顶点进行矩阵变换、插入顶点形成虚线之类的功能。
变换矩阵(trans_affine)
在认识转换管道之前,先了解一下AGG的变换矩阵。通过顶点坐标与矩阵的运行,我们可以得到新的坐标。关于图像的矩阵运算,MSDN里 有一篇关 于GDI+矩阵运算的文章,很值得一看
#include <agg_trans_affine.h>
类型
trans_affine
成员变量
double sx,shy,shx,sy,tx,ty; |
这六个变量组成一个2*3的矩阵,与坐标计算后得到一个新的坐标。比如对点(x,y)进行变换,则新的点(x',y') 为: x' = x*sx + y*shx + tx;
y' = x*shy + y*sy + ty; |
void transform(double* x,double* y) const; |
用上面的公式转换x,y坐标 |
const trans_affine& scale(double s); const trans_affine& scale(double x,double y); |
缩放 |
const trans_affine& rotate(double a); |
旋转,弧度单位(pi/180) |
const trans_affine& translate(double x,double y) |
平移 |
trans_affine operator * (const trans_affine& m); |
矩阵乘法 |
const trans_affine& invert(); |
取反矩阵 |
坐标转换管道中有个叫conv_transform的 转换器,它能利用矩阵对源顶点进行变换,我们先在这里玩玩吧^_^
加入头文件 #include "agg_conv_transform.h"
把on_draw()方法的里从“// Vertex Source”到“// Scanline Rasterizer”之间的代码改写成:
-
- agg::ellipse ell(0,50,50);
-
- agg::trans_affine mtx;
- mtx.scale(0.5,1);
- mtx.rotate(agg::deg2rad(30));
- mtx.translate(100,100);
- typedef agg::conv_transform<agg::ellipse> ell_ct_type;
- ell_ct_type ctell(ell,mtx);
- typedef agg::conv_contour<ell_ct_type> ell_cc_type;
- ell_cc_type ccell(ctell);
- typedef agg::conv_stroke<ell_cc_type> ell_cc_cs_type;
- ell_cc_cs_type csccell(ccell);
得到的图形是:
注:trans_affine不 仅仅用于源顶点的变换,在AGG库中有不少地方都能看到它。比如后面会讲到的线段(span)生成器,通过变换矩阵,就能够 自由变换填充于多边形之内的图案。
坐标转换管道
#include <agg_conv_stroke.h> // conv_stroke
#include <agg_conv_dash.h> // conv_dash
#include <agg_conv_marker.h> // conv_marker
#include <agg_conv_curve.h> // conv_curve
#include <agg_conv_contour.h> // conv_contour
#include <agg_conv_smooth_poly1.h> // conv_smooth_poly1.h
#include <agg_conv_bspline.h> // conv_bspline
#include <agg_conv_transform.h> // conv_transform
类型(演示程序基于基于此处代码)
template<class VertexSource, class Markers = null_markers> struct conv_stroke; |
变成连续线 构造参数为VertexSource width属性决定线宽。 |
在例 程的ell_cc_cs_type csccell(ccell); 后面加上csccell.width(3);线宽就会变成3。
|
template<class VertexSource, class Markers = null_markers> struct conv_dash; |
虚线 构造参数为VertexSource 用add_dash设置虚线长度和间隔 与conv_stroke套用 |
typedef agg::conv_contour<agg::ellipse> ell_cc_type;
ell_cc_type ccell(ell);
typedef agg::conv_dash<ell_cc_type> ell_cd_type;
ell_cd_type cdccell(ccell);
cdccell.add_dash(5,5);
typedef agg::conv_stroke<ell_cd_type> ell_cc_cs_type;
ell_cc_cs_type csccell(cdccell);
... |
template<class MarkerLocator, class MarkerShapes> class conv_marker; |
建立标记 |
请参考arrowhead示例代码
|
template<class VertexSource> struct conv_contour; |
轮廓变换 构造参数为VertexSource width属性决定扩展或收缩轮廓。 |
见例 程代码 |
template<class VertexSource> struct conv_smooth_poly1_curve; |
圆滑过渡多边形各顶点(贝塞尔) 构造参数为VertexSource smooth_value属性决定圆滑度(默认为1) |
在例 程on_draw()方法最后加入下面代码 triangle t(100,100,50);
agg::conv_smooth_poly1_curve<triangle> cspct(t);
ras.add_path(cspct);
agg::render_scanlines_aa_solid(
ras,sl,renb,agg::rgba8(255,0,0)); 三角形就变得圆头圆脑啦^_^ |
template<class VertexSource> struct conv_bspline; |
圆滑过渡多义线各顶点(贝塞尔) 构造参数为VertexSource interpolation_step属性决定步长。 |
在例 程on_draw()方法最后加入下面代码 triangle t(100,50);
agg::conv_bspline<triangle> cspct(t);
ras.add_path(cspct);
agg::render_scanlines_aa_solid(
ras,0)); 三角形也能变得圆头圆脑 |
template<class VertexSource, class Curve3 = curve3, class Curve4 = curve4> class conv_curve; |
可识别VertexSource中的曲线信息 构造参数为VertexSource。conv_smooth_poly1_curve 就是基于它实现的。 |
例程里的顶点都没有曲线信息,算了, 到后面讲到文字输出时会用到它的。 |
template<class VertexSource, class Transformer = trans_affine> class conv_transform; |
矩阵变换 用变换矩阵重新计算顶点位置 构造参数为VertexSource和变换矩阵 |
见变换矩阵一节的例子
|
作者:毛毛 来源:www.cppprog.com