有一个更简单的方法flip a Graphics
object.
创建一个Matrix这是结果矩阵乘法需要应用于指定对象的所有转换。
矩阵变换可以应用于图形路径对象或Graphics
目的。或两者兼而有之,当需要顺序执行多个转换时。
互联网System.Drawing.Drawing2D
Matrix 类没有预先构建的Flip
(镜像)变换,但是这个 Matrix 结构已经众所周知(我不确定这就是 Matrix 类中没有特定方法的原因):
| 1 | 0 | 0 | |-1 | 0 | 0 | | 1 | 0 | 0 |
| 0 | 1 | 0 | | 0 | 1 | 0 | | 0 |-1 | 0 |
| 0 | 0 | 1 | | 0 | 0 | 1 | | 0 | 0 | 1 |
Identity Mirror X-Axis Mirror Y-Axis
Matrix Matrix Matrix
您可以注意到(文档中也有报告)第三列始终相同,因此,在构建新矩阵时,第三列值是隐含的并由 Matrix 类初始化提供,因此我们仅指定前 2 列。
重要提示,直接来自 Matrix 类文档:
Caution:
复合变换的顺序很重要。一般来说,旋转,然后缩放,然后平移与
缩放,然后旋转,然后平移。类似地,矩阵的阶数
乘法很重要。一般来说,ABC与BAC不一样
绘制在 a 上的字符串的示例Panel
使用 GraphicsPath.AddString() method.
两个矩阵变换被添加到GraphicsPath
object:
a Flip-X
and a Flip-Y
,它们使用组合Matrix.Multiply()
method:
The Flip-X
and Flip-Y
构建的矩阵包括X
and Y
翻译,应用于每个的第三行Matrix
。
翻译值由以下因素决定Canvas方面。
例如,Flip-X
矩阵:
With a [Canvas].Width = 100 =>
:
旋转元件:X轴以原点为中心旋转180°(-1弧度)Point(0, 0)
.
翻译元素: 翻译X
位置100
右侧的图形单位(正值)。
| -1 | 0 | 0 |
| 0 | 1 | 0 |
| 100 | 0 | 1 |
Mirror X-Axis
Translate X +100
Matrix
效果的视觉表示。
代码中引用的控件与您在此处看到的相同(如果您需要重现它)。
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Text;
bool flipX = false;
bool flipY = false;
bool outlined = false;
float sampleFontEmSize = 28f;
string sampleText = "Sample Text to Flip";
FontFamily sampleFont = new FontFamily("Segoe UI");
private void panel1_Paint(object sender, PaintEventArgs e)
{
Panel panel = sender as Panel;
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
using (var path = new GraphicsPath())
using (var format = new StringFormat(StringFormatFlags.NoClip | StringFormatFlags.NoWrap))
{
format.Alignment = StringAlignment.Center;
format.LineAlignment = StringAlignment.Center;
path.AddString(sampleText, sampleFont, (int)FontStyle.Regular, sampleFontEmSize, panel.ClientRectangle, format);
using (var flipXMatrix = new Matrix(-1, 0, 0, 1, panel.Width, 0))
using (var flipYMatrix = new Matrix(1, 0, 0, -1, 0, panel.Height))
using (var transformMatrix = new Matrix())
{
if (flipX) {
transformMatrix.Multiply(flipXMatrix);
}
if (flipY) {
transformMatrix.Multiply(flipYMatrix);
}
path.Transform(transformMatrix);
//Or e.Graphics.Transform = TransformMatrix;
if (outlined) {
e.Graphics.DrawPath(Pens.LawnGreen, path);
}
else {
e.Graphics.FillPath(Brushes.Orange, path);
}
}
}
}
private void btnFlipX_Click(object sender, EventArgs e)
{
flipX = !flipX;
panel1.Invalidate();
}
private void btnFlipY_Click(object sender, EventArgs e)
{
flipY = !flipY;
panel1.Invalidate();
}
private void chkOutlined_CheckedChanged(object sender, EventArgs e)
{
outlined = chkOutlined.Checked;
panel1.Invalidate();
}