Реализую специализированный 2D-редактор в .NET. Хочу реализовать масштабирование относительно курсора.
В GDI+ у класса Graphics есть замечательное свойство Transform, которое позволяет с помощью аппарата аффинных преобразований в матричной форме реализовать то, что мне нужно. Во всех книжках пишут, что для масштабирования относительно произвольной точки необходимо:
- выполнить преобразование смещения так, чтобы точка относительно которой масштабируем сместилась в начало координат
- выполнить непосредственно масштабирование относительно начала координат
- выполнить преобразование смещение так, чтобы начало координат сместилось в исходную точку.
То есть в рамках моего приложения достаточно правильным образом менять матрицу Transform при вращении колесика мыши.
Делаю так:
public class DrawingAreaControl : UserControl
{
public DrawingAreaControl()
{
DoubleBuffered = true;
transform = new Matrix();
}
public Matrix transform { get; set; }
protected override void OnPaint(PaintEventArgs e)
{
e.Graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
e.Graphics.Transform = transform;
base.OnPaint(e);
}
const float SCALE_MUL = 1.05f;
protected override void OnMouseWheel(MouseEventArgs e)
{
base.OnMouseWheel(e);
transform.Multiply(new Matrix(1, 0, 0, 1, e.Location.X, e.Location.Y));
transform.Multiply(e.Delta > 0 ?
new Matrix(SCALE_MUL, 0, 0, SCALE_MUL, 0, 0) :
new Matrix(1 / SCALE_MUL, 0, 0, 1 / SCALE_MUL, 0, 0));
transform.Multiply(new Matrix(1, 0, 0, 1, -e.Location.X, -e.Location.Y));
Invalidate();
}
}
но это не работает так как надо. После нескольких масштабирований, рисунок под мышкой начинает убегать и уже нет нужного масштабирования относительно курсора.
По любому это из-за неправильного расчета преобразований в начало координат и обратно.
Как вычислить их, чтобы работало правильно?