Координаты чертежа карты без искажений в C#
Сообщение позволяет вам легко сопоставить прямоугольник при рисовании координат прямоугольника в координатах устройства. Часто, однако, вы хотите, чтобы область рисования не искажалась. Другими словами, вы не хотите, чтобы изображение растягивалось по вертикали или по горизонтали.
В этом примере используется следующий метод, чтобы сделать прямоугольник при рисовании координат прямоугольником в координатах устройства, делая прямоугольник рисования как можно большим, не искажая его.
// Карта из координат мира в координаты устройства
// без искажений.
private void SetTransformationWithoutDisortion(Graphics gr,
RectangleF world_rect, RectangleF device_rect,
bool invert_x, bool invert_y)
{
// Получите пропорции.
float world_aspect = world_rect.Width / world_rect.Height;
float device_aspect = device_rect.Width / device_rect.Height;
// Астрономический прямоугольник для сохранения соотношения сторон.
float world_cx = world_rect.X + world_rect.Width / 2f;
float world_cy = world_rect.Y + world_rect.Height / 2f;
if (world_aspect > device_aspect)
{
// Мировые координаты слишком короткие и ширины.
// Сделайте их выше.
float world_height = world_rect.Width / device_aspect;
world_rect = new RectangleF(
world_rect.Left,
world_cy - world_height / 2f,
world_rect.Width,
world_height);
}
else
{
// Мировые координаты слишком высокие и тонкие.
// Расширяем их.
float world_width = device_aspect * world_rect.Height;
world_rect = new RectangleF(
world_cx - world_width / 2f,
world_rect.Top,
world_width,
world_rect.Height);
}
// Сопоставьте новые координаты мира в координатах устройства.
SetTransformation(gr, world_rect, device_rect,
invert_x, invert_y);
}
Этот метод сначала вычисляет пропорции (отношение ширины к высоте) для мира и прямоугольников устройства. Если мировое соотношение сторон больше, чем соотношение сторон устройства, то мировой прямоугольник относительно короткий и широкий по сравнению с прямоугольником устройства. В этом случае код вычисляет новую высоту, чтобы сделать мир прямоугольником выше, поэтому он имеет ту же форму, что и прямоугольник устройства. Он использует новую высоту, чтобы создать новый прямоугольник мира по центру.
И наоборот, если соотношение сторон в мире меньше, чем соотношение сторон устройства, тогда мировой прямоугольник относительно высокий и тонкий по сравнению с прямоугольником устройства. В этом случае код вычисляет новую ширину, чтобы сделать мир прямоугольником шире, поэтому он имеет ту же форму, что и прямоугольник устройства. Он использует новую ширину для создания нового прямоугольника мира, центрированного по сравнению с исходным.
В этот момент новый прямоугольник мира и прямоугольник устройства имеют одинаковые формы, поэтому программа просто вызывает метод SetTransformation, описанный в более ранняя публикация . Поскольку два прямоугольника имеют одинаковые пропорции, это преобразование не искажает область рисования.
Пример программы использует следующий код для демонстрации метода SetTransformationWithoutDisortion.
// Нарисуйте смайлик как можно больше без искажений.
private void picCanvas_Paint(object sender, PaintEventArgs e)
{
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
// Установите преобразование. Переверните вертикально.
RectangleF drawing_rect = new RectangleF(-1, -1, 2, 2);
const int margin = 4;
Rectangle device_rect = new Rectangle(
margin, margin,
picCanvas.ClientSize.Width - 2 * margin,
picCanvas.ClientSize.Height - 2 * margin);
SetTransformationWithoutDisortion(e.Graphics,
drawing_rect, device_rect, false, true);
// Рисуем смайлик.
DrawSmiley(e.Graphics);
// Сбросьте преобразование и нарисуем вокруг него поле.
e.Graphics.ResetTransform();
e.Graphics.DrawRectangle(Pens.Red, device_rect);
}
Этот код создает мировой прямоугольник с -1 & le; X & le; 1 и -1 & le; Y & le; 1, потому что это область, в которой метод DrawSmiley рисует смайлик. Это делает прямоугольник устройства подходящим для PictureBox за вычетом маржи. Затем он вызывает SetTransformationWithoutDisortion для сопоставления координат мира с координатами устройства и вызывает метод DrawSmiley.
