Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 3c0a2c3

Browse files
Add Arc, Box, Regular_hexagon and other examples of classes and their usage
1 parent 2cc439e commit 3c0a2c3

File tree

22 files changed

+922
-1
lines changed

22 files changed

+922
-1
lines changed

‎ch13/extra.tex‎

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
% !TEX encoding = UTF8
2+
% !TEX spellcheck = ru_RU
3+
% !TEX root = ../seminars.tex
4+
5+
%%================================
6+
\section{Правильный шестиугольник}
7+
%%================================
8+
Рассмотрим класс \code{Regular\_hexagon} из~упражнения~8 \textbookref{главы~13}. Правильный шестиугольник, по~сути, является многоугольником \code{Polygon}. Однако он не~может содержать количество вершин, отличное от~6-ти. Таким образом, заманчиво наследовать от~\code{Polygon}, но тогда функцию \code{add()}, добавляющую дополнительные точки, необходимо как-то исключить из~интерфейса. И хотя, в~принципе, некоторые языки (с~динамической типизацией) позволяют сделать это, наследование интерфейса нарушилось бы. То есть там, где требуется \code{Polygon} мы не~смогли бы использовать \code{Regular\_hexagon}, в~который нельзя добавлять точки.
9+
10+
Хоть это лишает нас возможности воспользоваться реализацией классов \code{Polygon} или \code{Closed\_polyline}, \emph{логически правильным} решением является наследовать от~абстрактной фигуры \code{Shape}:
11+
\cppfile[firstline=49, lastline=61]{projects/lib/Graph_lib/ext/graph.h}
12+
13+
В~конструкторе добавляем точки, используя вращательную симметрию:
14+
\cppfile[firstline=99, lastline=113]{projects/lib/Graph_lib/ext/graph.cpp}
15+
16+
\noindent Округление при~помощи функции \code{std::round()} вместо отбрасывания дробной части даёт возможность слегка улучшить качество рисования в~отдельных случаях.
17+
18+
В~реализации следующих методов, которые предоставляются для~удобства пользователей, применяется априорное знание об~ориентации шестиугольника на~плоскости:
19+
\cppfile[firstline=115, lastline=133]{projects/lib/Graph_lib/ext/graph.cpp}
20+
21+
Заметим, что эти функции можно было бы вынести из~класса, то есть сделать внешними по~отношению к~классу. Тем не~менее, мы расположили их внутри, поскольку это свойства самих объектов и эти свойства есть у~подобных объектов других типов. Например, у~окна также есть длина (\code{x\_max()}) и ширина (\code{y\_max()}).
22+
23+
Код оставшейся функции \code{draw\_lines()} в~точности повторяет реализацию из~классов \code{Open\_polyline} и \code{Closed\_polyline}:
24+
\cppfile[firstline=135, lastline=157]{projects/lib/Graph_lib/ext/graph.cpp}
25+
26+
Пример рисования правильных шестиугольников показан на~рисунке~\ref{fig:regularhexagon}.
27+
28+
29+
30+
%%==================================
31+
\section{Мозаика из~шестиугольников}
32+
%%==================================
33+
Применим разработанный класс \code{Regular\_hexagon} для~рисования мозаики в~пределах прямоугольной области из~упражнения~9 \textbookref{главы~13}.
34+
35+
\begin{figure}[ht]
36+
{\centering
37+
\includegraphics[width=0.6\textwidth]{images/hexagon_tiles.png}
38+
39+
}
40+
\caption{Элементы мозаики из~правильных шестиугольников}
41+
\label{fig:regularhexagon}
42+
\end{figure}
43+
44+
Наследование выполним от~класса \code{Rectangle}, а для~хранения множества правильных шестиугольников воспользуемся классом \code{Vector\_ref}:
45+
46+
\cppfile[firstline=64, lastline=76]{projects/lib/Graph_lib/ext/graph.h}
47+
48+
Вся работа по~формированию мозаики выполняется в~конструкторе. Параметры~\code{p}, \code{ww} и~\code{hh} задают прямоугольник, который заполняется одинаковыми правильными шестиугольниками. Размер шестиугольников определяется радиусом описанной окружности \code{rr}. Код конструктора приведён ниже:
49+
50+
\cppfile[firstline=160, lastline=190]{projects/lib/Graph_lib/ext/graph.cpp}
51+
52+
\begin{figure}[ht]
53+
{\centering
54+
\includegraphics[width=0.6\textwidth]{images/tile_window.png}
55+
56+
}
57+
\caption{Окно, полностью заполненное мозаикой}
58+
\label{fig:hexagontile}
59+
\end{figure}
60+
61+
Реализация перекрывающих методов выполняется тривиально:
62+
63+
\cppfile[firstline=192, lastline=204]{projects/lib/Graph_lib/ext/graph.cpp}
64+
65+
В~начале мы рисуем прямоугольник, затем мозаику. По~умолчанию, прямоугольник не~рисуется. Это поведение мы установили в~конструкторе класса, задав невидимый цвет. Если изменить цвет рисования, то мы увидим границу (и заливку) прямоугольной области, как показано на~рисунке~\ref{fig:regularhexagon}. На~рисунке~\ref{fig:hexagontile} мозаикой покрыта вся область окна.

‎ch13/graphics_classes.tex‎

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
% !TEX encoding = UTF8
2+
% !TEX spellcheck = ru_RU
3+
% !TEX root = ../seminars.tex
4+
5+
%%==========================
6+
\chapter{Графические классы}
7+
%%==========================
8+
В~качестве образца приведём несколько примеров решения упражнений. Выполняя некоторые упражнения, мы по~сути расширяем графическую библиотеку, поэтому включим все новые классы в~пространство имён \code{Graph\_lib}. Весь этот код разместим в~каталоге \code{projects/lib/Graph\_lib/ext}. Заголовки и определения классов в~файле \code{graph.h}:
9+
10+
\cppfile[lastline=2, linenos=false]{projects/lib/Graph_lib/ext/graph.h}
11+
\cpp`// ... (may be some standard headers)`
12+
\cppfile[firstline=6, lastline=9, linenos=false]{projects/lib/Graph_lib/ext/graph.h}
13+
\cpp`// ... (extension classes)`
14+
\cppfile[firstline=78, linenos=false]{projects/lib/Graph_lib/ext/graph.h}
15+
16+
\noindent а реализацию функций "--- в~\code{graph.cpp}:
17+
18+
\cpp`// ... (some more standard headers)`
19+
\cppfile[firstline=4, lastline=7, linenos=false]{projects/lib/Graph_lib/ext/graph.cpp}
20+
\cpp`// ... (methods implementation)`
21+
\cppfile[firstline=206, linenos=false]{projects/lib/Graph_lib/ext/graph.cpp}
22+
23+
24+
25+
%%===================
26+
\section{Дуга (арка)}
27+
%%===================
28+
Рассмотрим класс \code{Arc} для~рисования дуги (или арки) из~упражнения~1 \textbookref{главы~13}. Дуга должна быть частью эллипса. Соответственно, разумно в~качестве базового класса выбрать \code{Ellipse}. Это позволит использовать часть уже разработанной функциональности.
29+
30+
\begin{figure}[ht]
31+
{\centering
32+
\includegraphics[height=0.25\textwidth]{images/arc.png}~\textit{a})
33+
\hfil
34+
\includegraphics[height=0.25\textwidth]{images/cross_wheel.png}~\textit{б})
35+
\hfil
36+
\includegraphics[height=0.25\textwidth]{images/box.png}~\textit{в})
37+
38+
}
39+
\caption{Рожицы из~арок и мальтийский крест}
40+
\label{fig:arc}
41+
\end{figure}
42+
43+
\cppfile[firstline=11, lastline=28]{projects/lib/Graph_lib/ext/graph.h}
44+
45+
\noindent
46+
Ограничений на~начальный и конечный углы дуги мы не~накладываем.
47+
48+
В~конструкторе необходимо инициализировать часть, соответствующую базовому классу \code{Ellipse}, а затем углы, которые мы добавили для~арки:
49+
\cppfile[firstline=9, lastline=13]{projects/lib/Graph_lib/ext/graph.cpp}
50+
51+
В~наиболее сложной части, а именно, отрисовке фигуры, мы взяли за~основу функцию из~класса \code{Ellipse}. Всё, что нужно, "--- это изменить углы:
52+
\cppfile[firstline=15, lastline=28]{projects/lib/Graph_lib/ext/graph.cpp}
53+
54+
Теперь мы можем нарисовать рожицу из~нескольких дуг, используя класс \code{Arc}, например, как показано на~рисунке~\ref{fig:arc}\textit{a}. Нос добавлен при~помощи метки \code{Mark}.
55+
56+
57+
58+
%%============================================
59+
\section{Прямоугольник с~закруглёнными углами}
60+
%%============================================
61+
Теперь рассмотрим класс \code{Box} из~упражнения~2 \textbookref{главы~13}. Он очень похож на~обычный прямоугольник. Единственное, что необходимо добавить, "--- радиус скругления углов. После не~слишком удачной реализации с~хранением четырёх линий в~объекте \code{Lines} и четырёх дуг в~массиве из~объектов \code{Arc}, мы решили наследовать от~\code{Rectangle}:
62+
\cppfile[firstline=31, lastline=46]{projects/lib/Graph_lib/ext/graph.h}
63+
64+
Если пользователь не~указал радиус скругления, мы решили по~умолчанию задать величину 10,円\% от~наименьшей стороны. Это удобно. Но поскольку эта величина известна только на~этапе выполнения, необходим некий трюк. Мы задали в~качестве значения по~умолчанию (константа \code{automatic}) наибольшее целое число, представимое типом \code{int} (необходим заголовок \code{<limits>}).
65+
66+
Реализация первого конструктора довольно проста, отрицательные радиусы скругления мы отбрасываем:
67+
\cppfile[firstline=31, lastline=40]{projects/lib/Graph_lib/ext/graph.cpp}
68+
69+
Второй конструктор совершенно аналогичен. Следует инициализировать базовую часть "--- класс \code{Rectangle} "--- двумя угловыми точками, а для~получения длины и ширины в~теле конструктора можно воспользоваться методами \code{width()} и \code{height()}.
70+
71+
Функция изменения радиуса скругления \code{set\_roundness()} также должна выполнить проверку на~неотрицательность аргумента, после чего присвоить новый радиус.
72+
73+
Стоит уделить внимание отрисовке. Она несколько сложнее, чем для~арки или прямоугольника, особенно, если добавить поддержку заливки фигуры цветом. Код функции представлен ниже:
74+
\cppfile[firstline=53, lastline=60]{projects/lib/Graph_lib/ext/graph.cpp}
75+
\cpp` // ... use fl_pie() and fl_rectf()`
76+
\cppfile[firstline=72, lastline=88]{projects/lib/Graph_lib/ext/graph.cpp}
77+
78+
Добавим контуры нашей рожице и несколько рамок с~разным скруглением, используя класс \code{Box}, например, как показано на~рисунке~\ref{fig:arc}\textit{в}.
79+
80+
81+
82+
%%================
83+
\input{ch13/extra}
84+
%%================
85+
86+
87+
88+
%%================
89+
\WhatToReadSection
90+
%%================
91+
\textcite{Stroustrup:2016:ru}: \textbf{глава~14}
92+
93+
94+
95+
%%===============
96+
\ExercisesSection
97+
%%===============
98+
\begin{exercise}
99+
\item Выполните упражнения из~\textbookref{главы~13} учебника.
100+
101+
\item При~вписывании \emph{золотой спирали} в~последовательность вложенных друг в~друга золотых прямоугольников, она аппроксимируется спиралью, построенной по~методу Дюрера. Золотой прямоугольник можно разделить на~квадрат и подобный ему прямоугольник, его, в~свою очередь, разделить тем же образом, и продолжать этот процесс произвольное число раз. Если в~эти квадраты вписать соединенные между собой четвертинки окружностей, то получается спираль, изображённая на~рисунке~\ref{fig:spirals:a} зелёным цветом.
102+
103+
\medskip
104+
105+
\begin{figure}[ht]
106+
{\centering
107+
\hfill
108+
\subbottom[Спираль Дюрера\label{fig:spirals:a}]{%
109+
\includegraphics[height=0.25\textwidth, frame]{images/fake_real_log_spiral.png}}
110+
\hfill
111+
\subbottom[Спираль Фибоначчи\label{fig:spirals:b}]{%
112+
\includegraphics[height=0.25\textwidth]{images/fibonacci_spiral.png}}
113+
\hfill
114+
}
115+
\caption{Приближения золотой спирали}
116+
\label{fig:spirals}
117+
\end{figure}
118+
119+
Спираль Фибоначчи строится подобно вышеописанной спирали, за~исключением того, что начинают с~прямоугольника из~двух квадратов и добавляют потом к~большей стороне прямоугольника квадрат такой же длины. Поскольку отношение между соседними числами Фибоначчи стремится к~золотой пропорции, спираль всё больше приближается к~золотой спирали по~мере добавления квадратов.
120+
121+
\begin{figure}[ht]
122+
{\centering
123+
\includegraphics[height=0.25\textwidth]{images/fibonacci_spiral_draw.png}
124+
\hspace{1.5cm}
125+
\includegraphics[height=0.25\textwidth]{images/snail.png}
126+
127+
}
128+
\caption{Спираль Фибоначчи}
129+
\label{fig:fibonaccispiral}
130+
\end{figure}
131+
132+
Нарисуйте спираль Фибоначчи, используя класс \code{Arc}, который был создан в~одном из~упражнений.
133+
\end{exercise}

‎images/arc.png‎

5.33 KB
Loading[フレーム]

‎images/box.png‎

6.36 KB
Loading[フレーム]

‎images/cross_wheel.png‎

8.62 KB
Loading[フレーム]

‎images/fake_real_log_spiral.png‎

137 KB
Loading[フレーム]

‎images/fibonacci_spiral.png‎

117 KB
Loading[フレーム]

‎images/fibonacci_spiral_draw.png‎

8.56 KB
Loading[フレーム]

‎images/hexagon_tiles.png‎

14.6 KB
Loading[フレーム]

‎images/snail.png‎

690 KB
Loading[フレーム]

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /