Пользователь
Регистрация: 01.03.2016
Сообщений: 24
|
Аффинные преобразования
Доброго времени суток!
Возникло 2 вопроса:
1) Создание горячих клавиш: брал образец кода на msdn, но суть в том, что, например, я ввел 100 в х в перемещении, по идеи оно должно при нажатии Alt + F3 только перемещаться, а оно перемещается сразу после нажатия Alt и соответственно вторая горячая клавиша не работает. Как исправить?
2) Как реализовать отражение относительно координатных осей(x, y) и прямой Y = X?
Код:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.BackColor = Color.White;
this.KeyPreview = true;
// Подписка на обработчик события рисования в drawingPanel:
panel1.Paint += new PaintEventHandler(panel1Paint);
}
private void panel1Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
DrawAxis(g);
ApplyTransformation(g);
}
private void ApplyTransformation(Graphics g)
{
// Новая матрица преобразования
Matrix m = new Matrix();
// Определяем центр
m.Translate(panel1.Width / 2, panel1.Height / 2);
// Перемещение
if (rbTranslation.Checked)
{
int dx = Convert.ToInt16(tbTranslationX.Text);
int dy = -Convert.ToInt16(tbTranslationY.Text);
m.Translate(dx, dy);
}
// Маштабирование
else if (rbScale.Checked)
{
float sx = Convert.ToSingle(tbScaleX.Text);
float sy = Convert.ToSingle(tbScaleY.Text);
m.Scale(sx, sy);
}
// Поворот
else if (rbRotation.Checked)
{
float angle = Convert.ToSingle(tbRotaionAngle.Text);
float x = Convert.ToSingle(tbRotateAtX.Text);
float y = -Convert.ToSingle(tbRotateAtY.Text);
g.FillEllipse(Brushes.Black, x - 4, y - 4, 8, 8);
m.RotateAt(angle, new PointF(x, y));
}
// Сдвиг
else if (rbShear.Checked)
{
float alpha = Convert.ToSingle(tbShearX.Text);
float beta = Convert.ToSingle(tbShearY.Text);
m.Shear(alpha, beta);
}
g.Transform = m;
DrawFigure(g, Color.Black);
}
private void DrawFigure(Graphics g, Color color)
{
Pen p = new Pen(Color.Navy, 3);
g.DrawEllipse(p, -50, -50, 100, 100);
g.DrawRectangle(p, -46, -16, 92, 30);
}
private void DrawAxis(Graphics g)
{
Matrix m = new Matrix();
// определяем матрицу преобразований
m.Translate(panel1.Width / 2, panel1.Height / 2);
// Применяем матрицу преобразования к графическому объекту:
g.Transform = m;
// Рисуем оси x и y:
g.DrawLine(Pens.Blue, -panel1.Width / 2, 0,panel1.Width / 2, 0);
g.DrawLine(Pens.Blue, 0, -panel1.Height / 2,0, panel1.Height / 2);
// Добавляем метки к осям X и Y:
g.DrawString("X", this.Font, Brushes.Blue, panel1.Width / 2 - 20, -20);
g.DrawString("Y", this.Font, Brushes.Blue, 5, -panel1.Height / 2 + 5);
// Рисуем деления:
int tick = 40;
StringFormat sf = new StringFormat();
sf.Alignment = StringAlignment.Far;
for (int i = -200; i <= 200; i += tick)
{
g.DrawLine(Pens.Blue, i, -3, i, 3);
g.DrawLine(Pens.Blue, -3, i, 3, i);
SizeF sizeXTick = g.MeasureString(i.ToString(),
this.Font);
if (i != 0)
{
g.DrawString(i.ToString(), this.Font, Brushes.Blue,
i + sizeXTick.Width / 2, 4f, sf);
g.DrawString((-i).ToString(), this.Font, Brushes.Blue,
-3f, i - sizeXTick.Height / 2, sf);
}
else
{
g.DrawString("0", this.Font, Brushes.Blue,
new PointF(i - sizeXTick.Width / 3, 4f), sf);
}
}
}
private void button1_Click_1(object sender, EventArgs e)
{
panel1.Invalidate();
}
private void button2_Click(object sender, EventArgs e)
{
//Сбрасываем параметры к исходным
tbTranslationX.Text = "0";
tbTranslationY.Text = "0";
tbScaleX.Text = "1";
tbScaleY.Text = "1";
tbRotaionAngle.Text = "0";
tbRotateAtX.Text = "0";
tbRotateAtY.Text = "0";
tbShearX.Text = "0";
tbShearY.Text = "0";
panelbm.Invalidate();
}
private void button1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.F3 && e.Modifiers == Keys.Alt)
{
button1.PerformClick();// имитируем нажатие button1
}
}
private void button2_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.F2 && e.Modifiers == Keys.Alt)
{
button2.PerformClick();// имитируем нажатие button2
}
}
}
Проект прилагается.
|