- •Аннотация
- •Введение
- •1. Первый раздел
- •Занятие 1
- •Занятие 2
- •Занятие 3
- •Занятие 4
- •1.2 Формирование траектории для движения простого геометрического объекта
- •Выводы:
- •Занятие 5
- •Занятие 6
- •Второй раздел
- •Индивидуальное Задание 1
- •2.1. Первый подраздел второго раздела Формулировка задания:
- •Математическую постановка:
- •Описание используемых элементов для интерфейса и их настройка (свойства):
- •Кнопки управления
- •Ползунки trackBar
- •Метки Lables
- •Ввод координат
- •Выпадающие списки
- •Меню выбора цветов MenuStrip
- •FillColorToolStripMenuItem — Цвет заливки - Выбор цвета заливки шестиугольника borderColorToolStripMenuItem — Цвет контура - Выбор цвета границы шестиугольника
- •Системные компоненты
- •Описание используемых графических примитивов:
- •Кривая траектории яйца Хюгельшеффера
- •Движущийся объект - шестиугольник
- •Примеры работы с учетом изменения параметров:
- •Выводы:
- •3. Третий раздел индивидуальное Задание 2
- •3.1. Первый подраздел третьего раздела
- •Формулировка задания:
- •Математическая постановка:
- •Описание используемых элементов для интерфейса и их настройка:
- •Общие настройки формы
- •Области отрисовки PictureBox
- •Элемент управления уровнем фрактала — NumericUpDown
- •Метки - lLabels
- •5. Цветовая палитра (внутри программы)
- •Описание используемых графических примитивов:
- •1. Окружности
- •Текст программы:
- •Примеры работы программы:
- •Заключение
Метки - lLabels
|
levelLabel -Отображение диапазона уровней фракталов |
label1 - Отображение названия фрактала |
Свойство |
Значение |
Значение |
Font |
Arial, размер 10 |
Times New Roman, 16, Bold |
Text |
пустой, задаётся программно |
Четверные окружности |
Location |
X = 820, Y = 103 |
X = 149, Y = 21 |
|
label2 - Подпись к дереву построения |
label3 - Подпись к элементу выбора уровней |
Свойство |
Значение |
Значение |
Font |
Times New Roman, 16, Bold |
Times New Roman, 12 |
Text |
Times New Roman, 16, Bold |
Изменить количество уровней: |
Location |
X = 804, Y = 207 |
X = 591, Y = 73 |
5. Цветовая палитра (внутри программы)
Используется в построении фрактала:
array<Color>^ colors = gcnew array<Color> {Color::Purple, Color::DarkCyan, Color::Black, Color: Firebrick, Color::Orange, Color::Snow};
Каждому уровню фрактала присваивается свой цвет, чередующийся по модулю.
Описание используемых графических примитивов:
Графическая часть программы реализована с использованием возможностей пространства имён System::Drawing, которое предоставляет средства для построения двумерной графики в среде Windows Forms. Основу визуализации фрактала и дерева построения составляют следующие графические примитивы:
1. Окружности
Каждый узел фрактала и узел дерева отображается на экране в виде окружности. Для их отрисовки используется метод DrawEllipse, который принимает координаты и радиус. В случае фрактала отображаются только контуры окружностей (Pen), в дереве построения окружности заливаются цветом (SolidBrush) для лучшей визуализации уровней. Цвет окружности определяется в зависимости от уровня узла. Все окружности рисуются в координатах, предварительно рассчитанных и сохранённых в каждом узле дерева.
2. Прямые линии
Для отображения связей между родительскими и дочерними узлами в дереве используются прямые линии методом DrawLine. Каждое соединение отражает структуру иерархии. Цвет линий соответствует цвету родительского узла.
3. Текстовые надписи
Внутри каждого узла дерева отображается текст — номер уровня соответствующего узла - метод DrawString. Шрифт - Arial, размер 8, цвет текста — чёрный.
4. Цвета
Для различения уровней дерева и фрактала используется массив предопределённых цветов, Purple, DarkCyan, Black, Firebrick, Orange, Snow. Цвет выбирается в зависимости от уровня по формуле:
colors[currentLevel % colors->Length];
5. Масштабирование и координаты
До отрисовки фрактала и дерева все координаты и радиусы узлов масштабируются под размеры окна с помощью функций, которые вычисляют итоговые координаты x и y, а также радиус для каждого узла.
Текст программы:
#pragma once
#include <windows.h>
#include <math.h>
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
public ref class MainForm : public System::Windows::Forms::Form {
private:
ref class FractalNode {
public:
int level; float x, y; float originalX, originalY; float radius;Color color;
System::Collections::Generic::List<FractalNode^>^ children;
FractalNode(int lvl, float x, float y, float r, Color c)
: level(lvl), x(x), y(y), originalX(x), originalY(y), radius(r), color(c) {
children = gcnew System::Collections::Generic::List<FractalNode^>(); }};
System::Collections::Generic::List<FractalNode^>^ allFractals;
System::Windows::Forms::Label^ levelLabel; // в объявлении класса
FractalNode^ treeSourceFractal;
System::Int32 maxLevel;
PictureBox^ fractalPictureBox;
PictureBox^ treePictureBox;
private: System::Windows::Forms::Label^ label1;
private: System::Windows::Forms::Label^ label2;
private: System::Windows::Forms::Label^ label3;
NumericUpDown^ levelNumericUpDown;
FractalNode^ BuildFractalTree(int targetLevel, int currentLevel, float x, float y, float radius) {
array<Color>^ colors = gcnew array<Color> {
Color::Purple, Color::DarkCyan, Color::Black, Color::Firebrick,
Color::Orange, Color::Snow };
FractalNode^ node = gcnew FractalNode(currentLevel, x, y, radius,
colors[currentLevel % colors->Length]);
if (currentLevel < targetLevel) {
float newRadius = radius / 2.0f;
array<PointF>^ directions = gcnew array<PointF> {
PointF(0.0f, -newRadius),PointF(0.0f, newRadius),
PointF(-newRadius, 0.0f), PointF(newRadius, 0.0f)};
for each (PointF dir in directions) {
node->children->Add(BuildFractalTree(targetLevel, currentLevel + 1,
x + dir.X, y + dir.Y, newRadius)); }}return node; }
void CalculateFractalCoordinates(FractalNode^ node, float scaleX, float scaleY, float offsetX, float offsetY) {
if (node == nullptr) return;
node->x = node->originalX * scaleX + offsetX;
node->y = node->originalY * scaleY + offsetY;
node->radius = node->radius * (scaleX + scaleY) / 2.0f;
for each (FractalNode ^ child in node->children) {
CalculateFractalCoordinates(child, scaleX, scaleY, offsetX, offsetY); } }
void CalculateTreeCoordinates(FractalNode^ node, float treeX, float treeY, float levelHeight, float scale) {
if (node == nullptr) return;
node->x = treeX;
node->y = treeY;
node->radius = 10.0f * scale;
if (node->children->Count > 0) {
float childY = treeY + levelHeight;
float totalWidth = (float)Math::Pow(2, node->level) * 50.0f * scale;
float childX = treeX - totalWidth / 2.0f;
float step = totalWidth / (node->children->Count);
for (int i = 0; i < node->children->Count; i++) {
CalculateTreeCoordinates(node->children[i], childX + step * (i + 0.5f),
childY, levelHeight * 0.8f, scale);} }}
void DrawFractal(Graphics^ g, FractalNode^ node) {
Pen^ pen = gcnew Pen(node->color, 2);
g->DrawEllipse(pen, node->x - node->radius, node->y - node->radius,
node->radius * 2.0f, node->radius * 2.0f);
for each (FractalNode ^ child in node->children) {
DrawFractal(g, child); } }
void DrawTree(Graphics^ g, FractalNode^ node) {
if (node == nullptr) return;
SolidBrush^ brush = gcnew SolidBrush(node->color);
RectangleF nodeRect(node->x - node->radius, node->y - node->radius,
node->radius * 2.0f, node->radius * 2.0f);
g->FillEllipse(brush, nodeRect);
System::Drawing::Font^ font = gcnew System::Drawing::Font("Arial", 8);
String^ levelText = node->level.ToString();
SizeF textSize = g->MeasureString(levelText, font);
g->DrawString(levelText, font, Brushes::Black,
node->x - textSize.Width / 2.0f, node->y - textSize.Height / 2.0f);
for each (FractalNode ^ child in node->children) {
g->DrawLine(gcnew Pen(node->color, 1), node->x, node->y, child->x, child->y);
DrawTree(g, child);}}
void RebuildFractals() {
if (fractalPictureBox->Image != nullptr) delete fractalPictureBox->Image;
if (treePictureBox->Image != nullptr) delete treePictureBox->Image;
allFractals = gcnew System::Collections::Generic::List<FractalNode^>();
int cols = 2; int rows = (maxLevel + cols - 1) / cols;
float spacingX = fractalPictureBox->Width / (cols + 1);float spacingY = fractalPictureBox->Height / (rows + 1);
for (int level = 0; level < maxLevel; level++) {
float centerX = spacingX * (1 + (level % cols)); float centerY = spacingY * (1 + (level / cols));
FractalNode^ fractal = BuildFractalTree(level, 0, centerX, centerY,
Math::Min(spacingX, spacingY) / 2.1f);
allFractals->Add(fractal);}
treeSourceFractal = BuildFractalTree(maxLevel - 1, 0,
treePictureBox->Width / 2.0f, 50.0f, 40.0f);
for each (FractalNode ^ fractal in allFractals) {
CalculateFractalCoordinates(fractal, 1.0f, 1.0f, 0.0f, 0.0f);}
float scale = Math::Min(treePictureBox->Width / 800.0f, treePictureBox->Height / 600.0f);
CalculateTreeCoordinates(treeSourceFractal, treePictureBox->Width / 2.0f, 50.0f * scale,
100.0f * scale, scale);
Bitmap^ fractalBmp = gcnew Bitmap(fractalPictureBox->Width, fractalPictureBox->Height);
Graphics^ fractalG = Graphics::FromImage(fractalBmp);
fractalG->Clear(Color::White);
fractalG->SmoothingMode = System::Drawing::Drawing2D::SmoothingMode::AntiAlias;
for each (FractalNode ^ f in allFractals) {
DrawFractal(fractalG, f); }
fractalPictureBox->Image = fractalBmp;
Bitmap^ treeBmp = gcnew Bitmap(treePictureBox->Width, treePictureBox->Height);
Graphics^ treeG = Graphics::FromImage(treeBmp);
treeG->Clear(Color::White);
treeG->SmoothingMode = System::Drawing::Drawing2D::SmoothingMode::AntiAlias;
DrawTree(treeG, treeSourceFractal);
treePictureBox->Image = treeBmp;
levelLabel->Text = String::Format("Уровни фракталов: 0 - {0}", maxLevel - 1); }
public:
MainForm(void) {
InitializeComponent();
this->maxLevel = System::Decimal::ToInt32(this->levelNumericUpDown->Value);
RebuildFractals(); }
private: System::Void label1_Click(System::Object^ sender, System::EventArgs^ e) {}};
[STAThread]
int main(array<String^>^ args) {
Application::EnableVisualStyles();
Application::SetCompatibleTextRenderingDefault(false);
Application::Run(gcnew MainForm());
return 0;}
