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

2019-08-03 13:52

图13-13 伸缩(1.5, 0.5)

图13-14 镜像文本

Graphics graph(pDC->m_hDC);

Font font(L\宋体\

ifont(L\宋体\

SolidBrush textBrush(Color::Blue), mirrorBrush(Color::Gray); // 普通文本输出

CString str(L\镜像文本\

graph.DrawString(str, str.GetLength(), &font,

PointF(200.0f, 10.0f), &textBrush);

// 垂直镜像文本输出(上下倒置) graph.ScaleTransform(1, -1); graph.TranslateTransform(0, -120);

graph.DrawString(str, str.GetLength(), &ifont,

PointF(200.0f, 10.0f), &mirrorBrush);

// 水平镜像文本输出(左右倒置) graph.ResetTransform(); graph.ScaleTransform(-1, 1); graph.TranslateTransform(-220, 0);

graph.DrawString(str, str.GetLength(), &font,

PointF(0.0f, 10.0f), &mirrorBrush);

// 垂直+水平镜像文本输出(上下左右全倒置) graph.ResetTransform(); graph.ScaleTransform(-1, -1);

graph.TranslateTransform(-220, -120);

graph.DrawString(str, str.GetLength(), &ifont,

PointF(0.0f, 10.0f), &mirrorBrush);

又例如(镜像图像,参见图13-15):

21

Graphics graph(pDC->m_hDC); Image img(L\金泰熙.bmp\

REAL w = REAL(img.GetWidth()), h = REAL(img.GetHeight()); graph.DrawImage(&img, PointF(w, 0)); graph.ScaleTransform(1, -1);

graph.TranslateTransform(0, -2 * h); graph.DrawImage(&img, PointF(w, 0)); graph.ResetTransform(); graph.ScaleTransform(-1, 1); graph.TranslateTransform(-w, 0); graph.DrawImage(&img, PointF(0, 0)); graph.ResetTransform(); graph.ScaleTransform(-1, -1);

graph.TranslateTransform(-w, -2 * h); graph.DrawImage(&img, PointF(0, 0));

图13-15 镜像图像

4.混合变换

也可以将者3种变换结合起来,形成混合变换。注意变换的顺序,顺序不同,结果可能页不一样。

1)先旋转后伸缩——对应齐次坐标矩阵变换为:

?x'??sx00??cosα?sinα0??x??sx?cosα?sx?sinα0??x?????????????y'?0sy0sinαcosα0y?sy?sinαsy?cosα0???????????y? ?1??001??0?????01?001????????1????1?例如(参见图13-16):

Graphics graph(pDC->m_hDC);

Rect rectSquare(30, 10, 100, 100),

rectCircle(140, 10, 100, 100);

graph.DrawRectangle(&Pen(Color::Green), rectSquare); graph.DrawEllipse(&Pen(Color::Green), rectCircle); graph.ScaleTransform(1.5f, 0.5f);

22

graph.RotateTransform(30.0f);

graph.DrawRectangle(&Pen(Color::Red), rectSquare); graph.DrawEllipse(&Pen(Color::Red), rectCircle);

图13-16 旋转30度后再伸缩(1.5, 0.5) 图13-17 伸缩(1.5, 0.5)后再旋转30度 2)先伸缩后旋转——对应齐次坐标矩阵变换为:

?x'??cos?????y'???sin??1??0????sin?cos?00??sx00??x??sx?cos???????0??0sy0??y???sx?sin??????1?0??001??1???sy?sin?sy?cos?00??x????0??y? ??1???1?例如(参见图13-17):

Graphics graph(pDC->m_hDC);

Rect rectSquare(80, 10, 100, 100),

rectCircle(190, 10, 100, 100);

graph.DrawRectangle(&Pen(Color::Green), rectSquare); graph.DrawEllipse(&Pen(Color::Green), rectCircle); graph.RotateTransform(30.0f); graph.ScaleTransform(1.5f, 0.5f);

graph.DrawRectangle(&Pen(Color::Red), rectSquare); graph.DrawEllipse(&Pen(Color::Red), rectCircle);

上面的粗体代码部分,也可以替换为:

graph.ScaleTransform(1.5f, 0.5f);

graph.RotateTransform(30.0f, MatrixOrderAppend); // 右乘,后变换

又例如(旋转正方形,参见图13-18):

Graphics graph(pDC->m_hDC); CRect crect;

GetClientRect(&crect); // 获取当前客户区矩形 PointF cp(REAL(crect.CenterPoint().x),

23

REAL(crect.CenterPoint().y)); // 中心点

RectF rect(cp.X - 10.0f, cp.Y - 10.0f, 20.0f, 20.0f); // 原始矩形 REAL scale = 1.0f; // 初始放大倍数

//REAL scale = 0.0f, ds = 10.0f; // 用于矩形膨胀 for (int i = 0; i <= 360; i += 20) { // 循环 }

graph.TranslateTransform(cp.X, cp.Y); // 设置旋转中心 //rect.Inflate(scale * ds, scale * ds); // 膨胀矩形 graph.ScaleTransform(scale, scale); // 放大 graph.RotateTransform(REAL(i)); // 旋转

graph.TranslateTransform(-cp.X, -cp.Y); // 还原坐标原点 graph.DrawRectangle(&Pen(Color::Green), rect); // 绘制矩形 Sleep(100); // 暂停100毫秒(0.1秒)

graph.ResetTransform(); // 重置所有变换(还原为恒等变换) //rect.Inflate(-scale * ds, -scale * ds); // 还原矩形原大小 scale += 1.0f; // 放大倍数加1

图13-18 旋转并放大矩形

图13-19 旋转并膨胀矩形

在上例中,因为矩形的框线随矩形一起被放大,所以边框越来越粗。如果注释掉语句:

//REAL scale = 1.0f; 和 //graph.ScaleTransform(scale, scale);

并去掉原来的三个注释符,把对整个图形的放大改为只有矩形本身膨胀(inflate):

rect.Inflate(scale * ds, scale * ds);

则框线将保持单个像素粗,输出结果如图13-19。

这里使用了矩形类Rect和RectF的方法Inflate(膨胀):

24

VOID Inflate(INT dx, INT dy); VOID Inflate(const Point& point); VOID Inflate(REAL dx, REAL dy); VOID Inflate(const PointF& point);

将原矩形的左右和上下分别膨胀dx和dy个逻辑单位(默认为像素),矩形的中心不变。

5.矩阵变换

除了上面所讲的3种基本变换外,图形类还可以设置复杂的矩阵变换。有关的方法为:

Status SetTransform(const Matrix *matrix); // 设置变换矩阵为matrix

Status ResetTransform(VOID); // 设置变换矩阵为单位矩阵(恒等变换)(还原) 例如(相当于前面的先旋转后伸缩,参见图13-20):

Graphics graph(pDC->m_hDC);

REAL radian = 3.1415926f / 180.0f;

Rect rectSquare(80/*30*/, 10, 100, 100),

rectCircle(190/*140*/, 10, 100, 100);

REAL sx = 1.5f, sy = 0.5f, a = 30.0f;

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

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

Matrix m(m11, m12, m21, m22, m31, m32);

graph.DrawRectangle(&Pen(Color::Green), rectSquare); graph.DrawEllipse(&Pen(Color::Green), rectCircle); graph.SetTransform(&m);

graph.DrawRectangle(&Pen(Color::Red), rectSquare); graph.DrawEllipse(&Pen(Color::Red), rectCircle);

若将上面rectSquare的X值改为30、rectCircle的X值改为140、m12中的sy改为sx、m21中的-sx改为-sy,则输出结果如图13-21所示(相当于前面的先伸缩后旋转)。

25


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

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

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

马上注册会员

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