В итоге будет получено следующее изображение:
Очевидно, что класс 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()
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: