- •Министерство образования Республики Беларусь
- •Введение
- •Анализ исходного графического объекта и методов преобразования фигур
- •1.1.Математическое описание преобразования плоских фигур
- •1.2 Выбор и обоснование языка программирования и среды разработки
- •Разработка алгоритма работы программы
- •3. Описание основных компонентов программы и последовательности разработки
- •4.Исходный код программы
- •5.Проверка корректности работы программы в различных режимах
- •Заключение
- •Литература
Разработка алгоритма работы программы
Изучение геометрических свойств фигур и закономерностей для вписанных друг в друга простых двумерных фигур.
Изучение математических функций для расчета движения траектории движения фигур на плоскости.
Изучение зависимостей координат углов фигур для создания анимации движения фигур вокруг своей оси.
Выбор и добавление необходимых компонентов на форму.
Реализация полученных формул на языке С++
Настройка компонентов для возможности управления фигурой и траекторией ее движения
3. Описание основных компонентов программы и последовательности разработки
Общий алгоритм построения рисунка:
Рисунок 3.1 – Общий алгоритм построения рисунка
4.Исходный код программы
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
int dir = 1; // направление движение
double scale = 1; // масштаб объекта
int rux=0;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
Amplitude->Max = Form1->Height - (OuterRadius->Text*2*scale);
}
//---------------------------------------------------------------------------
// функция для отрисовки звезды в окружности
void TForm1::star_in_circle (TPoint center, int outer_radius, int inner_radius, int beam_count, double scale, TColor color1, TColor color2, double angle)
{
// center - центр фигуры
// outer_radius и inner_radius - внешний (окружность) и внутр. радиусы (на этой окружности лежат основания лучей)
// beam_count - кол-во лучей, scale - масштаб
// color - цвет фигуры
// angle - угол (поворота / наклона лучей звезды)
Refresh();
// применяем масштаб
outer_radius *= scale;
inner_radius *= scale;
Canvas->Pen->Width = 1;
Canvas->Pen->Color = clBlack;
Canvas->Brush->Color = color2;
// рисуем квадрат
Canvas->Rectangle(center.x - outer_radius, center.y - outer_radius, center.x + outer_radius + 1, center.y + outer_radius + 1);
// переходим в "начальную точку" звезды
Canvas->MoveTo(center.x+sin(angle)*outer_radius, center.y-cos(angle)*outer_radius);
// рисуем лучи
if (ColorVershini->Checked==false) {
Canvas->Brush->Color = color2;
Canvas->FloodFill(center.X, center.Y, clBlack, fsBorder);
}
else
{
for(int i = 1; i <= beam_count; i++)
{
Canvas->LineTo(center.x+sin(angle+(i*2-1)*M_PI/beam_count*dir)*inner_radius, center.y-cos(angle+(i*2-1)*M_PI/beam_count*dir)*inner_radius);
Canvas->LineTo(center.x+sin(angle+i*2*M_PI/beam_count*dir)*outer_radius, center.y-cos(angle+i*2*M_PI/beam_count*dir)*outer_radius);
}
Canvas->Brush->Color = color1;
Canvas->FloodFill(center.X, center.Y, clBlack, fsBorder);
}
Canvas->MoveTo(center.x+sin(angle)*outer_radius, center.y-cos(angle)*outer_radius);
for (int i = 1; i <= beam_count; i++)
{
Canvas->LineTo(center.x+sin(angle+(i*2-1)*M_PI/beam_count*dir)*inner_radius, center.y-cos(angle+(i*2-1)*M_PI/beam_count*dir)*inner_radius);
// Canvas->LineTo(center.x+sin(angle+(i*2-3)*M_PI/beam_count*dir)*inner_radius, center.y-cos(angle+(i*2-3)*M_PI/beam_count*dir)*inner_radius);
Canvas->MoveTo(center.x+sin(angle+(i*2-1)*M_PI/beam_count*dir)*inner_radius, center.y-cos(angle+(i*2-1)*M_PI/beam_count*dir)*inner_radius);
Canvas->LineTo(center.x+sin(angle+i*2*M_PI/beam_count*dir)*outer_radius, center.y-cos(angle+i*2*M_PI/beam_count*dir)*outer_radius);
}
if (ColorVershini->Checked==false) {
Canvas->Brush->Color = color1;
}
else {
Canvas->Brush->Color = color2;
}
//Заливка звезды
Canvas->FloodFill(center.X, center.Y, clBlack, fsBorder);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ResetClick(TObject *Sender)
{
Tag = 0;
Timer1->Tag = 0;
dir = 1;
scale = StrToFloatDef(EditScale1->Text, 1) / StrToFloatDef(EditScale2->Text, 1);
EditScale1->Clear();
EditScale2->Clear();
BeamCount->Text=6;
InnerRadius->Text=45;
OuterRadius->Text=110;
CSpinEditMovingSpeed->Text=10;
CSpinEditRotatingSpeed->Text=10;
CSpinEditTimeToChangeDirection->Text=1;
EditScale1->Text=1;
EditScale2->Text=1;
Amplitude->Position=50;
SpeedLy->Position=10;
Moving->Checked=true;
ColorVershini->Checked=false;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
// скорость движения и масштаб
Timer1->Interval = CSpinEditMovingSpeed->MaxValue - CSpinEditMovingSpeed->Value + 1;
scale = StrToFloatDef(EditScale1->Text, 1) / StrToFloatDef(EditScale2->Text, 1);
// начальные значения
/*
Timer1->Interval = 10;
Timer1->Enabled = 1;
Timer2->Interval = 0 ;
Timer1->Enabled = 0;
ClientHeight = 500, ClientWidth = 1000 ;
CSpinEditRotatingSpeed->Value = 10;
CSpinEditTimeToChangeDirection->Value = 0 ;
CSpinEditRotatingSpeed->MaxValue = 100 ;
CSpinEditRotatingSpeed->MinValue = 1 ;
CSpinEditTimeToChangeDirection->MaxValue = 5 ;
CSpinEditTimeToChangeDirection->MinValue = 0 ;
*/
CSpinEditMovingSpeed->MaxValue = 100 ;
CSpinEditMovingSpeed->MinValue = 1 ;
// задаем радиусы и кол-во лучей
int outer_radius = StrToIntDef(OuterRadius->Text, 1), inner_radius = StrToIntDef(InnerRadius->Text, 1), beam_count = StrToIntDef(BeamCount->Text, 1);
// задаем кординаты центра фигуры
// int x = Tag+outer_radius*scale, y = (Amplitude->Position*(-1))*sin(Tag*180./ClientWidth/15/M_PI)+ClientHeight-outer_radius*scale-1;
//синусоида
int x = Tag+outer_radius*scale, y = -100*sin(Tag*180./ClientWidth/1.5/M_PI)+0.75*ClientHeight-outer_radius*scale-1;
float R = (float)x/ClientWidth*255,
B = (float)(ClientWidth-x)/ClientWidth*255;
// фигура строится вначале в левом нижнем углу, туда и возвращается (поэтому проверка ниже упрощена)
star_in_circle(TPoint(x, y), outer_radius, inner_radius, beam_count, scale, TColor(RGB(B,B,R)), TColor(RGB(0,R,B)), Timer1->Tag*180./M_PI/ClientWidth/50*CSpinEditRotatingSpeed->Value);
// проверка на достижение фигурой границ формы
if (((x+outer_radius*scale >= ClientWidth || y-outer_radius*scale <= 0 || y+outer_radius*scale >= ClientHeight) && dir > 0) || (x-outer_radius*scale <= 0 && dir < 0))
{
// меняем направление движения
dir *= -1;
Timer1->Enabled = 0;
// задаем время, через которое фигура начнет двигаться в другую сторону
Timer2->Interval = CSpinEditTimeToChangeDirection->Value*1000 + 1;
Timer2->Enabled = 1;
}
// смещаем фигуру
Tag += dir+(SpeedLy->Position*dir);
// если нужно менять и направление вращения, то замени Timer1->Tag выше (идет "построение" фигуры) на Tag
// Timer1->Tag тогда не нужен
if (Moving->Checked==true) {
Timer1->Tag=Tag;
}
else {
Timer1->Tag++;
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Timer2Timer(TObject *Sender)
{
Timer2->Enabled = 0;
Timer1->Enabled = 1;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::CSpinEditMovingSpeedChange(TObject *Sender)
{
if (CSpinEditMovingSpeed->Value>=CSpinEditMovingSpeed->MaxValue) {
ShowMessage("Максимальное значение - 100");
CSpinEditMovingSpeed->Value=100;
Timer1->Interval = CSpinEditMovingSpeed->MaxValue;
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormResize(TObject *Sender)
{
Amplitude->Max = Form1->Height - (OuterRadius->Text*2*scale+100);
if(Amplitude->Position > Amplitude->Max) Amplitude->Position = Amplitude->Max;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::StartClick(TObject *Sender)
{
if(Timer1->Enabled) {
Timer1->Enabled = false;
Start->Caption = "Старт";
}
else {
Timer1->Enabled = true;
Start->Caption = "Стоп";
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Panel1MouseMove(TObject *Sender, TShiftState Shift, int X,
int Y)
{
rux = 1;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormMouseMove(TObject *Sender, TShiftState Shift, int X, int Y)
{
rux = -1;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormShow(TObject *Sender)
{
Panel1->Left = -690;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Timer3Timer(TObject *Sender)
{
if (rux>0 && Panel1->Left < -2) Panel1->Left += 50;
if (rux<0)
if (Panel1->Left > -670) Panel1->Left -= 50;
else { Panel1->Left -670; rux=0; }
}
//---------------------------------------------------------------------------