Читаем Программирование полностью

В итоге будет получено следующее изображение:



Очевидно, что класс Marks можно использовать для отображения дискретных данных, изображать которые с помощью ломаной было бы неуместно. В качестве примера можно привести пары (рост, вес), характеризующие группу людей.

Класс Marks — это разновидность класса Marked_polyline с невидимыми линиями.


struct Marks : Marked_polyline {

  Marks(const string& m) :Marked_polyline(m)

  {

    set_color(Color(Color::invisible));

  }

};

13.16. Класс Mark

Объект класса Point задает координаты в объекте класса Window. Иногда мы их отображаем, а иногда нет. Если возникает необходимость пометить отдельную точку, чтобы ее увидеть, мы можем изобразить ее в виде крестиков, как показано в разделе 13.2, или воспользоваться классом Marks. Это объяснение слегка многословно, поэтому рассмотрим простой объект класса Marks, инициализированный точкой и символом.

Например, мы могли бы пометить центры окружностей, изображенных в разделе 13.12, следующим образом:


Mark m1(Point(100,200),'x');

Mark m2(Point(150,200),'y');

Mark m3(Point(200,200),'z');

c1.set_color(Color::blue);

c2.set_color(Color::red);

c3.set_color(Color::green);


В итоге мы получили бы изображения, приведенные ниже.



Класс Mark — это разновидность класса Marks, в котором при создании объекта немедленно задается начальная (и, как правило, единственная) точка.


struct Mark : Marks {

  Mark(Point xy, char c) : Marks(string(1,c))

  {

    add(xy);

  }

};


Функция string(1,c) — это конструктор класса string, инициализирующий строку, содержащую единственный символ c.

Класс Mark всего лишь позволяет легко создать объект класса Marks с единственной точкой, помеченной единственным символом. Стоило ли тратить силы, чтобы определять такой класс? Или он является следствием “ложного стремления к усложнениям и недоразумениям”? Однозначного и логичного ответа на этот вопрос нет. Мы много думали над этим и в конце концов решили, что для пользователей этот класс был бы полезен, а определить его было совсем нетрудно.

Почему в качестве метки используется символ? Можно было бы нарисовать любую маленькую фигуру, но символы нагляднее и проще. Они часто позволяют отделить одно множество точек от другого. К тому же такие символы, как x, o, + и *, обладают центральной симметрией. 

13.17. Класс Image

Файлы в типичном персональном компьютере хранят тысячи изображений. Кроме того, миллионы изображений доступны в сети веб. Естественно, мы хотели бы отображать содержимое этих файлов на экране с помощью относительно простых программ. Например, ниже продемонстрирован рисунок (rita_path.gif), иллюстрирующий путь урагана “Рита”, пришедшего из Мексиканского залива.

Мы можем выбрать часть этого изображения и добавить фотографию урагана, сделанную из космоса (rita.jpg).


Image rita(Point(0,0),"rita.jpg");

Image path(Point(0,0),"rita_path.gif");

path.set_mask(Point(50,250),600,400); // выбираем желательную область

win.attach(path);

win.attach(rita);


Операция set_mask() выбирает часть рисунка, которую следует изобразить на экране. В данном случае мы выбрали изображение размером 600×400 пикселей из файла rita_path.gif (загруженный как объект path) и показали его в области, левый верхний угол которой имеет координаты (50,250). Выбор части рисунка — довольно распространенный прием, поэтому мы предусмотрели для него отдельную операцию.



Фигуры изображаются одна поверх другой, подобно листам бумаги, в порядке их добавления на экран. По этой причине объект path оказался на самом “дне”, просто потому, что он был связан с окном до объекта rita. Изображения могут кодироваться во множестве форматов. Здесь мы используем только два из них: JPEG и GIF.


struct Suffix {

  enum Encoding { none, jpg, gif };

};


В нашей библиотеке графического интерфейса изображение в памяти представляется как объект класса Image.


struct Image:Shape {

  Image(Point xy, string file_name,

    Suffix::Encoding e = Suffix::none);

  ~Image() { delete p; }

  void draw_lines() const;

  void set_mask(Point xy, int ww, int hh)

    { w=ww; h=hh; cx=xy.x; cy=xy.y; }

private:

Перейти на страницу:
Нет соединения с сервером, попробуйте зайти чуть позже