GDI+高级编程 - 图文(6)

2019-08-03 13:52

图13-20 矩阵变换图 (旋转30度+伸缩(1.5, 0.5))

13-21 矩阵变换

(伸缩(1.5, 0.5)+旋转30度)

13.3.2 矩阵变换*

在GDI+中,矩阵变换(matrix transformation)所涉及的矩阵,由专门的矩阵类Matrix来表示。不过这里的矩阵,不仅可以用于图形变换,也可以用于图像、颜色、路径、区域等对象的变换。GDI+中的3×3的矩阵变换,对应于几何上(用齐次坐标表示)的仿射变换(affine transformation):

? 非齐次坐标的列向量形式:

?x'??sx?cosα?sy?sin???x??dx???y'?????sx?sinαsy?cos?????y?????dy?? ????????? 齐次坐标的列向量形式(一般):

?x'??sx?cos?????y'???sx?sin??1??0???? 齐次坐标的行向量形式(GDI+):

?sy?sin?sy?cos?0dx??x????dy??y?

??1???1??x'y'1???x?sx?cos??y1???sy?sin??dx?sx?sin?sy?cos?dy0??0? 1??其中,sx、α、dx和sy、β、dy分别为x和y方向的伸缩比例、旋转角度、平移量(在GDI+中,一般取α=β)。

例如,只旋转不伸缩,但是设y方向的旋转角度为b = 60度与x方向的a = 30度不同。将上例中的矩阵元素计算部分改为:

Rect rectSquare(110, 10, 100, 100),

rectCircle(220, 10, 100, 100);

REAL sx = 1.0f, sy = 1.0f, a = 30.0f, b = 60.0f;

26

REAL m11 = sx * cos(a * radian), m12 = sy * sin(a * radian),

m21 = -sx * sin(b * radian), m22 = sy * cos(b * radian), m31 = 0.0f, m32 = 0.0f;

则输出结果如图13-22所示(其中右图为将上面的b改回为30度的输出结果)。

旋转(30, 60)度

旋转30度

图13-22 矩阵变换

1.矩阵类Matrix

矩阵类Matrix的构造函数有4个:

Matrix(VOID); // 单位矩阵

Matrix(const RectF &rect, const PointF *dstplg); // 实变换矩阵 Matrix(const Rect &rect, const Point *dstplg); // 整变换矩阵

Matrix(REAL m11, REAL m12, REAL m21, REAL m22, REAL dx, REAL dy);

其中:

?

?100???单位矩阵:M??010?= M T

?001???? 变换矩阵:

rect.Y0??rect.X?rect.X???TM??rect.Widthrect.Height0?,M??rect.Y?dstplg.X?0dstplg.Y1????或:

dstplg.X??rect.Heightdstplg.Y?

?01?rect.Width?m11m120??m11m21dx?????TM??m21m220?,M??m12m22dy?

?dx?0dy1?01?????对应的矩阵变换(仿射变换)为:

27

? 行向量形式(GDI+):

?x'y'1???xy1?M??xrect.Y0??rect.X??y1??rect.Widthrect.Height0???x?dstplg.Xdstplg.Y1???

?m11m120???y1??m21m220? ?dxdy1???? 列向量形式(一般):

?x'??x??rect.X?????T?y'??M?y???rect.Y?1??1??0?????rect.Widthdstplg.X??x??m11m21dx??x????????rect.Heightdstplg.Y??y???m12m22dy??y?

??1??0??0101???????1?实际上,GDI+中的矩阵并不是真正的3×3的(似上面),而只是3×2的(但与上面3

?0???×3的矩阵等价),剩下的最右一列(1)和?0?被省掉了:

?1????x'y'???x??xrect.Y??rect.X??y1?M3?2??xy1??rect.Widthrect.Height??dstplg.Xdstplg.Y???

?m11m12??sx?cosαsx?sinα?????y1??m21m22? ??xy1???sy?sinβsy?cosβ??dx?dy?dxdy?????其中:

m11?sx?cosα , m12?sx?sinα

m21??sy?sinβ , m22?sy?cosβ对应的:

m12m11

?m21?sy?m212?m222, ??tg?1???m22??sx?m112?m122, ??tg?12.矩阵方法

矩阵类Matrix提供了若干方法,用于获取矩阵信息以及进行各种矩形运算(按字母顺序排列):

Matrix *Clone(VOID); // 克隆

28

static BOOL Equals(const Matrix* matrix); // 相等

Status GetElements(REAL *m) const; // 获取元素数组(m11~m32) Status GetLastStatus(VOID); // 获取最后一次矩阵操作的状态 Status Invert(VOID); // 求逆(将当前矩阵用其逆矩阵代替) BOOL IsIdentity(VOID); // 判断是否为单位矩阵 BOOL IsInvertible(VOID); // 判断矩形是否可逆 // 相乘(将当前矩阵用与指定矩阵的乘积矩阵代替):

Status Multiply(const Matrix *matrix, MatrixOrder order = MatrixOrderPrepend); REAL OffsetX(VOID); // x偏移(返回变换矩阵的x向位移dx) REAL OffsetY(VOID); // y偏移(返回变换矩阵的y向位移dy) Status Reset(VOID); // 重置(用单位矩阵代替当前矩阵)

Status Rotate(REAL angle, MatrixOrder order = MatrixOrderPrepend); // 旋转 Status RotateAt(REAL angle, const PointF ¢er, // 相对于指定点旋转

MatrixOrder order = MatrixOrderPrepend);

Status Scale(REAL scaleX, REAL scaleY, MatrixOrder order = MatrixOrderPrepend); // 伸缩 // 设置矩阵元素:

Status SetElements(REAL m11, REAL m12, REAL m21, REAL m22, REAL dx, REAL dy); // 剪切(将当前矩阵用与指定剪切矩阵的乘积矩阵代替):

Status Shear(REAL shearX, REAL shearY, MatrixOrder order = MatrixOrderPrepend); Status TransformPoints(Point *pts, INT count = 1); // 变换整数点数组 Status TransformPoints(PointF *pts, INT count = 1); // 变换浮点数点数组 Status TransformVectors(Point *pts, INT count = 1); // 变换整数点向量 Status TransformVectors(PointF *pts, INT count = 1); // 变换浮点数点向量

Status Translate(REAL offsetX, REAL offsetY, MatrixOrder order = MatrixOrderPrepend); // 平移

3.剪切矩阵

方法Shear(剪切/滑移)的功能相当于投射变换,变换矩阵为

shearY??1??S??shearX1?

?00???

29

对应的坐标变换为:

?x'y'???xy1?S??xshearY??1??y1??shearX1???x?y?shearX?00???y?x?shearY?

例如(参见图13-23):

Graphics graph(pDC->m_hDC); SolidBrush brush(Color::Green); Rect rect(0, 0, 100, 100);

graph.FillRectangle(&SolidBrush(Color::Green), rect); Matrix M; M.Shear(1, 0.5f); graph.SetTransform(&M);

graph.FillRectangle(&SolidBrush(Color(128, 255, 0, 0)), rect); M.Reset(); M.Shear(0.5f, 1); graph.SetTransform(&M);

graph.FillRectangle(&SolidBrush(Color(128, 0, 0, 255)), rect); M.Reset(); M.Shear(2, 1); graph.SetTransform(&M);

graph.FillRectangle(&SolidBrush(Color(128, 255, 0, 255)), rect); M.Reset(); M.Shear(1, 2); graph.SetTransform(&M);

graph.FillRectangle(&SolidBrush(Color(128, 0, 255, 255)), rect);

图13-23 正方形(绿色)的剪切

图13-24 文本投影

又例如(文本投影,参见图13-24):

Graphics graph(pDC->m_hDC);

SolidBrush grayBrush(Color::Gray), redBrush(Color::Red);

30


GDI+高级编程 - 图文(6).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:中国铜管市场及投资调研报告目录

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: