О себе События Портфолио Статьи Гостевая Фотоальбом На злобу дня Ссылки Учеба Программы
Alex_K (г.Киров) - Алексей Кощеев
Хостинг и регистрация доменов в Кирове

Система координат объекта Canvas. Проблема масштабирования

TCanvas - объект для рисования на поверхности объектов. C++Builder и Delphi предоставляют расширенный доступ к Canvas используемых объектов. Такие классы объектов, как TForm, TLabel, TImage и другие позволяют использовать этот объект.

Итак, суть проблемы.

Прямая и точка в VB Пример (VB):
    picExample.DrawWidth = 2
    picExample.Scale (-10, 10)-(10, -20)
    picExample.PSet (0, 0)
    picExample.Line (-8, 7)-(7, -15)

Код задает левую верхнюю и правую нижнюю координаты масштаба. Далее строятся точка и линия, причём по координатам, которые задаются методом Scale.

В C++Builder и Delphi нет метода Scale и масштаб там следующий (0, 0)-(width, height), где width - ширина объекта, height - высота.

Решение проблемы - переход к новым координатам.

Необходимо сделать отображение (x0, y0)-->(x1, y1), где (x0, y0) - исходная точка, (x1, y1) - отображение точки в масштабе объекта (0, 0)-(width, height).

Используем линейную замену:

Отображение X Отображение Y

Теперь, какое бы значение мы не поставили из области, ограниченной прямоугольником (xmin, ymax)-(xmax, ymin), мы получим значения, которые будут лежать в области, ограниченной прямоугольником (0, 0)-(width, height), то есть в области, соответствующей объекту Canvas. Реализацию такого отображения координат удобно выполнить с помощью класса с методами Scalе, X, Y, setHeight, setWidth.

Заголовочный файл класса
#ifndef ConvertXYH
#define ConvertXYH
class ConvertXY{
     public:
            ConvertXY();
            void Scale(float, float, float, float);
            int X(float);
            int Y(float);
            void setHeight(int);
            void setWidth(int);
     private:
            float xmin, xmax, ymin, ymax;
            float h, w;
};
#endif

Файл класса
#include "ConvertXY.h"

ConvertXY::ConvertXY() {
     xmin = 0;
     xmax = 100;
     ymin = 0;
     ymax = 100;
}

void ConvertXY::Scale(float x1, float y1, float x2, float y2) {
     xmin = x1;
     ymax = y1;
     xmax = x2;
     ymin = y2;
}

int ConvertXY::X(float x) {
      return w * (xmin - x) / (xmin - xmax);
}

int ConvertXY::Y(float y) {
      return -h * (ymax - y) / (ymin - ymax);
}

void ConvertXY::setHeight(int height) {
     h = (height > 0) ? height : 0;
}

void ConvertXY::setWidth(int width) {
     w = (width > 0) ? width : 0;
}

Файл формы
   // ....
   ConvertXY obj;
   obj.setHeight(imgExample->Height);
   obj.setWidth(imgExample->Width);
   obj.Scale(-10, 10, 10, -20);
   imgExample->Canvas->Pen->Width=2;
   imgExample->Canvas->MoveTo(obj.X(0), obj.Y(0));
   imgExample->Canvas->LineTo(obj.X(0), obj.Y(0));
   imgExample->Canvas->MoveTo(obj.X(-8), obj.Y(7));
   imgExample->Canvas->LineTo(obj.X(7), obj.Y(-15));
   // ....

Теперь, легко можно осуществлять универсальное преобразование координат.

Алексей Кощеев
14.10.2002
Наверх  Посмотреть другие статьи
Fanshop.ru

Рейтинг@Mail.ru

Rambler's Top100

© Алексей Кощеев, г.Киров, 2001-2020 хостинг предоставлен компанией Айхэд