Вход/Регистрация
Программирование. Принципы и практика использования C++ Исправленное издание
вернуться

Страуструп Бьерн

Шрифт:

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

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

Как и ожидалось, результат идентичен тому, что мы получили в разделе 13.6, за исключением последнего отрезка.

Определение класса

Closed_polyline
приведено ниже.

struct Closed_polyline:Open_polyline { // замкнутый ряд линий

void draw_lines const;

};

void Closed_polyline::draw_lines const

{

Open_polyline::draw_lines; // сначала рисуем открытый ряд линий,

// затем рисуем замыкающую линию:

if (color.visibility)

fl_line(point(number_of_points–1).x,

point(number_of_points–1).y,

point(0).x,

point(0).y);

}

В классе

Closed_polyline
нужна отдельная функция
draw_lines
, рисующая замыкающую линию, которая соединяет последнюю точку с первой. К счастью, для этого достаточно реализовать небольшую деталь, которая отличает класс
Closed_polyline
от класса
Shape
. Этот важный прием иногда называют “программированием различий“ (“programming by difference”). Нам нужно запрограммировать лишь то, что отличает наш производный класс (
Closed_polyline
) от базового (
Open_polyline
).

Итак, как же нарисовать замыкающую линию? Воспользуемся функцией

fl_line
из библиотеки FLTK. Она получает четыре аргументы типа
int
, задающих четыре точки. И здесь нам снова понадобится графическая библиотека. Однако обратите внимание на то, что, как и во многих других ситуациях, упоминание библиотеки FLTK скрыто от пользователей. В программе пользователя нет никаких ссылок на функцию
fl_line
, и ей неизвестно ничего о неявном представлении точек в виде пар целых чисел. При необходимости мы могли бы заменить библиотеку FLTK другой библиотекой графического пользовательского интерфейса, а пользователи этого почти не заметили бы.

13.8. Класс Polygon

Класс Polygon очень похож на класс

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

cpl.add(Point(100,250));

Результат изображен ниже.

В соответствии с классическими определениями объект класса

Closed_polyline
многоугольником не является. Как определить класс
Polygon
так, чтобы он правильно отображал связь с классом
Closed_polyline
, не нарушая правил геометрии? Подсказка содержится в предыдущем описании. Класс
Polygon
— это класс
Closed_polyline
, в котором линии не пересекаются. Иначе говоря, мы могли бы подчеркнуть способ образования фигуры из точек и сказать, что класс
Polygon
— это класс
Closed_polyline
, в который невозможно добавить объект класса
Point
, определяющий отрезок линии, пересекающийся с одной из существующих линий в объекте класса
Polygon
.

Эта идея позволяет описать класс

Polygon
следующим образом:

struct Polygon:Closed_polyline { // замкнутая последовательность

// непересекающихся линий

void add(Point p);

void draw_lines const;

};

void Polygon::add(Point p)

{

// проверка того, что новая линия не пересекает существующие

// (код скрыт)

Closed_polyline::add(p);

}

Здесь мы унаследовали определение функции

draw_lines
из класса
Closed_polyline
, сэкономив усилия и избежав дублирования кода. К сожалению, мы должны проверить каждый вызов функции
add
. Это приводит нас к неэффективному алгоритму, сложность которого оценивается как N в квадрате, — определение объекта класса
Polygon
, состоящего из N точек, требует N*(N–1)/2 вызовов функции
intersect
. По существу, мы сделали предположение, что класс
Polygon
будет использоваться для создания многоугольников с меньшим количеством точек.

Например, для того чтобы создать объект класса

Polygon
, состоящего из 24 точек, потребуется 24*(24–1)/2 == 276 вызовов функции
intersect
. Вероятно, это допустимо, но если бы мы захотели создать многоугольник, состоящий из 2000 точек, то вынуждены были бы сделать около 2 000 000 вызовов. Мы должны поискать более эффективный алгоритм, который может вынудить нас модифицировать интерфейс.

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

Polygon poly;

  • Читать дальше
  • 1
  • ...
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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