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

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 помещается в окне. То, что выходит за пределы окна, “отрезается”; иначе говоря, на экране эта часть не отображается.

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