Существует более простой способ перевернуть a Graphics
объект.
Создайте Matrix , которая является результатом Matrix умножения всех преобразований, которые необходимо применить к указанному объекту.
Матричное преобразование может быть применено к объекту GraphicsPath или Graphics
. Или и то и другое, когда необходимо выполнить несколько преобразований последовательно.
. Matrix класс .Net System.Drawing.Drawing2D
не имеет предварительно созданного преобразования 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
Вы можете заметить (об этом также сообщается в Документах), что 3-й столбец всегда одинаков, поэтому при построении новой матрицы значения 3-го столбца подразумеваются и предоставляются инициализацией класса Matrix, поэтому мы указываем только элементы в первых 2 столбцах.
Важное примечание, прямо из документов класса Matrix:
Осторожно :
Порядок составного преобразования важен. В общем, поверните, затем масштабируйте, затем переведите не так, как
масштабировать, затем повернуть, затем перевести. Точно так же порядок матрицы
умножение важно. В общем, ABC не совпадает с BAC
Пример строки, нарисованной на Panel
с использованием GraphicsPath.AddString () метод .
Два объекта Matrix добавлены к объекту GraphicsPath
:
Flip-X
и Flip-Y
, которые объединяются с использованием метода Matrix.Multiply()
:
Матрицы Flip-X
и Flip-Y
построены, включая переводы X
и Y
, примененные к 3-й строке каждого Matrix
.
Значения перевода определяются размерами Canvas .
Например, матрица Flip-X
:
С [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;
string SampleText = "Sample Text to Flip";
bool FlipX = false;
bool FlipY = false;
bool Outlined = false;
private void panel1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
e.Graphics.CompositingMode = CompositingMode.SourceOver;
e.Graphics.CompositingQuality = CompositingQuality.HighQuality;
e.Graphics.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
using (GraphicsPath path = new GraphicsPath())
using (StringFormat format = new StringFormat(StringFormatFlags.NoClip | StringFormatFlags.NoWrap))
{
format.Alignment = StringAlignment.Center;
format.LineAlignment = StringAlignment.Center;
path.AddString(SampleText, new FontFamily("Segoe UI"), (int)FontStyle.Regular, 28, panel1.ClientRectangle, format);
using (Matrix FlipXMatrix = new Matrix(-1, 0, 0, 1, panel1.Width, 0))
using (Matrix FlipYMatrix = new Matrix(1, 0, 0, -1, 0, panel1.Height))
using (Matrix 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();
}