Чтение онлайн

на главную

Жанры

Программирование. Принципы и практика использования C++ Исправленное издание
Шрифт:

poly.add(Point(100,100));

poly.add(Point(150,200));

poly.add(Point(250,250));

poly.add(Point(300,200));

Очевидно, что этот фрагмент создает объект класса

Polygon
, идентичный (вплоть до последнего пикселя) исходному объекту класса
Closed_polyline
.

Проверка того, что объект класса

Polygon
действительно представляет собой многоугольник, оказывается на удивление запутанной. Проверка пересечений, которая реализована в функции
Polygon::add
, является наиболее сложной во всей графической библиотеке. Если вас интересуют кропотливые
геометрические манипуляции с координатами, взгляните на код. И это еще не все. Посмотрим, что произойдет, когда мы попытаемся создать объект класса
Polygon
лишь из двух точек. Лучше предусмотреть защиту от таких попыток.

void Polygon::draw_lines const

{

if (number_of_points < 3)

error("Меньше трех точек вводить нельзя.");

Closed_polyline::draw_lines;
}

Проблема заключается в том, что инвариант класса
Polygon
— “точки образуют многоугольник” — невозможно проверить, пока не будут определены все точки. Иначе говоря, в соответствии с настоятельными рекомендациями мы не задаем проверку инварианта в конструкторе класса
Polygon
. И все же “предупреждение о трех точках” в классе
Polygon::draw_lines
— совершенно недопустимый трюк. (См. также упр. 18.)

13.9. Класс Rectangle

Большинство фигур на экране являются прямоугольниками. Причина этого явления объясняется частично культурными традициями (большинство дверей, окон, картин, книжных шкафов, страниц и т.д. является прямоугольниками), а частично техническими особенностями (задать координаты прямоугольника проще, чем любой другой фигуры). В любом случае прямоугольник настолько широко распространен, что в системах графического пользовательского интерфейса он обрабатывается непосредственно, а не как многоугольник, имеющий четыре прямых угла.

struct Rectangle:Shape {

Rectangle(Point xy, int ww, int hh);

Rectangle(Point x, Point y);

void draw_lines const;

int height const { return h; }

int width const { return w; }

private:

int h; // высота

int w; // ширина

};

Мы можем задать прямоугольник двумя точками (левой верхней и правой нижней) или одной точкой, шириной и высотой. Конструкторы этого класса могут иметь следующий вид:

Rectangle::Rectangle(Point xy,int ww,int hh)
:w(ww),h(hh)

{

if (h<=0 || w<=0)

error("Ошибка: отрицательная величина");

add(xy);

}

Rectangle::Rectangle(Point x,Point y)
:w(y.x–x.x),h(y.y–x.y)

{

if (h<=0 || w<=0)

error("Ошибка: отрицательная ширина или длина.");

add(x);

}

Каждый

конструктор соответствующим образом инициализирует члены
h
и
w
(используя синтаксис списка инициализации; см. раздел 9.4.4) и хранит верхнюю левую точку отдельно в базовом классе
Shape
(используя функцию
add
). Кроме того, в конструкторах содержится проверка ширины и длины — они не должны быть отрицательными.

Одна из причин, по которым некоторые системы графики и графического пользовательского интерфейса рассматривают прямоугольники как отдельные фигуры, заключается в том, что алгоритм определения того, какие пиксели попадают внутрь прямоугольника, намного проще и, следовательно, быстрее, чем алгоритмы проверки для других фигур, таких как
Polygon
и
Circle
. По этой причине понятие “заполнение цветом” — т.е. закраска пространства внутри прямоугольника — чаще применяется по отношению к прямоугольникам, чем к другим фигурам.

Заполнение цветом можно реализовать в конструкторе или в виде отдельной функции

set_fill_color
(предусмотренной в классе
Shape
наряду с другими средствами для работы с цветом).

Rectangle rect00(Point(150,100),200,100);

Rectangle rect11(Point(50,50),Point(250,150));

Rectangle rect12(Point(50,150),Point(250,250)); // ниже rect11

Rectangle rect21(Point(250,50),200,100); // правее rect11

Rectangle rect22(Point(250,150),200,100); // ниже rect21

rect00.set_fill_color(Color::yellow);

rect11.set_fill_color(Color::blue);

rect12.set_fill_color(Color::red);

rect21.set_fill_color(Color::green);

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

Если заполнение цветом не требуется, то прямоугольник считается прозрачным; вот почему вы видите желтый угол объекта

rect00
.

Фигуры можно передвигать в окне (см. раздел 14.2.3). Рассмотрим пример.

rect11.move(400,0); // вправо от rect21

rect11.set_fill_color(Color::white);

win12.set_label("rectangles 2");

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

Заметьте, что только часть белого прямоугольника

rect11
помещается в окне. То, что выходит за пределы окна, “отрезается”; иначе говоря, на экране эта часть не отображается.

Обратите внимание на то, как фигуры накладываются одна на другую. Это выглядит так, будто вы кладете на стол один лист бумаги на другой. Первый лист окажется в самом низу. Наш класс
Window
(раздел Д.3) реализует простой способ размещения фигуры поверх другой (используя функцию
Window::put_on_top
). Рассмотрим пример.

win12.put_on_top(rect00);

win12.set_label("rectangles 3");

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

Поделиться:
Популярные книги

Измена. Ребёнок от бывшего мужа

Стар Дана
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Измена. Ребёнок от бывшего мужа

Отборная бабушка

Мягкова Нинель
Фантастика:
фэнтези
юмористическая фантастика
7.74
рейтинг книги
Отборная бабушка

Мимик нового Мира 3

Северный Лис
2. Мимик!
Фантастика:
юмористическая фантастика
постапокалипсис
рпг
5.00
рейтинг книги
Мимик нового Мира 3

Адский пекарь

Дрейк Сириус
1. Дорогой пекарь!
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Адский пекарь

Я еще не князь. Книга XIV

Дрейк Сириус
14. Дорогой барон!
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Я еще не князь. Книга XIV

Путь Шедара

Кораблев Родион
4. Другая сторона
Фантастика:
боевая фантастика
6.83
рейтинг книги
Путь Шедара

С Д. Том 16

Клеванский Кирилл Сергеевич
16. Сердце дракона
Фантастика:
боевая фантастика
6.94
рейтинг книги
С Д. Том 16

Бывший муж

Рузанова Ольга
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Бывший муж

Драконий подарок

Суббота Светлана
1. Королевская академия Драко
Любовные романы:
любовно-фантастические романы
7.30
рейтинг книги
Драконий подарок

Вечный. Книга I

Рокотов Алексей
1. Вечный
Фантастика:
боевая фантастика
попаданцы
рпг
5.00
рейтинг книги
Вечный. Книга I

Вираж бытия

Ланцов Михаил Алексеевич
1. Фрунзе
Фантастика:
героическая фантастика
попаданцы
альтернативная история
6.86
рейтинг книги
Вираж бытия

Вечный. Книга II

Рокотов Алексей
2. Вечный
Фантастика:
боевая фантастика
попаданцы
рпг
5.00
рейтинг книги
Вечный. Книга II

Наследница Драконов

Суббота Светлана
2. Наследница Драконов
Любовные романы:
современные любовные романы
любовно-фантастические романы
6.81
рейтинг книги
Наследница Драконов

Ретроградный меркурий

Рам Янка
4. Серьёзные мальчики в форме
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Ретроградный меркурий