Координаты чертежа карты без искажений в C#

Сообщение Легко отображать координаты чертежа в 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.

Источник: http://csharphelper.com/blog/2016/02/map-drawing-coordinates-without-distortion-in-c/

1 Звезда2 Звезды3 Звезды4 Звезды5 Звезд (Пока оценок нет)
Adblock
detector