Добавил:
надеюсь это добро кому-то поможет Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
практика лето 25 Программирование графического интерфейса и основы визуализации структур данных.docx
Скачиваний:
3
Добавлен:
09.07.2025
Размер:
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;}