Литмир - Электронная Библиотека
A
A
Программирование. Принципы и практика использования C++ Исправленное издание - _134.png

 

Программирование. Принципы и практика использования C++ Исправленное издание - _001.png
 Проблема заключается в том, что инвариант класса
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()
). Кроме того, в конструкторах содержится проверка ширины и длины — они не должны быть отрицательными.

 

Программирование. Принципы и практика использования C++ Исправленное издание - _002.png
 Одна из причин, по которым некоторые системы графики и графического пользовательского интерфейса рассматривают прямоугольники как отдельные фигуры, заключается в том, что алгоритм определения того, какие пиксели попадают внутрь прямоугольника, намного проще и, следовательно, быстрее, чем алгоритмы проверки для других фигур, таких как
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);

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

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

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

rect00
.

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

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

rect11.set_fill_color(Color::white);

win12.set_label("rectangles 2");

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

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

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

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

 

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

win12.put_on_top(rect00);

win12.set_label("rectangles 3");

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

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

Отметьте, что мы можем видеть линии, образующие прямоугольник, даже если он закрашен. Если такое изображение нам не нравится, то линии можно удалить.

180
{"b":"847443","o":1}