Nadesłany przez Tomasz Lubiński, 27 lipca 2005 01:00
Kod przedstawiony poniżej przedstawia główną część rozwiązania problemu.Pobierz pełne rozwiązanie.
Jeżeli nie odpowiada Ci sposób formatowania kodu przez autora skorzystaj z pretty printer'a i dostosuj go automatycznie do siebie.
L-systemy - program/Unit1.cpp:
//www.algorytm.org
//Tomasz Lubiński (c)2003
//L-systemy
#include <vcl.h>
#include <math.h>
#include <vector.h>
#pragma hdrstop
#include "Unit1.h"
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner){}
void __fastcall TForm1::Button1Click(TObject *Sender)
{
AnsiString produkcja,tmp;
AnsiString reguly[10];
int dlugosc,flaga,iteracji;
float kat,krok,przyrost_kat;
float dx,dy,x,y;
vector<int> stos_x, stos_y;
vector<float> stos_kat;
//zebranie danych z formularza
produkcja=Memo1->Lines->operator [](0);
for(int i=1; i<Memo1->Lines->Count; i++) reguly[i-1]=Memo1->Lines->operator [](i);
przyrost_kat=StrToFloat(LabeledEdit1->Text);
krok=StrToFloat(LabeledEdit2->Text);
iteracji=StrToInt(LabeledEdit3->Text);
//ustawienia początkowe (x,y - punkt startowy rysowania, kat - kąt początkowy, dx,dy-przesuniecia)
kat=0;
x=StrToInt(startX->Text);
y=Image1->Height-StrToInt(startY->Text);
dx=krok*cos(M_PI*kat/180);
dy=krok*sin(M_PI*kat/180);
//przygotowanie rysunku
Image1->Canvas->Rectangle(0,0,Image1->Width,Image1->Height);
Image1->Canvas->MoveTo(x,y);
//etap przetwarzania regul
for (int i=0; i<iteracji; i++)
{
dlugosc=produkcja.Length();
tmp=produkcja;
produkcja="";
for (int j=1; j<=dlugosc; j++)
{
flaga=0;
for (int k=0; k<Memo1->Lines->Count-1; k++)
if (reguly[k][1]==tmp[j])
{
flaga=1;
produkcja=produkcja+reguly[k].SubString(4,reguly[k].Length()-3);
break;
}
if (flaga==0) produkcja=produkcja+tmp[j];
}
}
//etap rysowania
dlugosc=produkcja.Length();
for (int j=1; j<=dlugosc; j++)
switch (produkcja[j])
{
case 'F' : x+=dx;
y+=dy;
Image1->Canvas->LineTo(x,y);
break;
case 'f' : x+=dx;
y+=dy;
Image1->Canvas->MoveTo(x,y);
break;
case '+' : kat+=przyrost_kat;
dx=krok*cos(M_PI*kat/180);
dy=krok*sin(M_PI*kat/180);
break;
case '-' : kat-=przyrost_kat;
dx=krok*cos(M_PI*kat/180);
dy=krok*sin(M_PI*kat/180);
break;
case '[' : stos_x.push_back(x);
stos_y.push_back(y);
stos_kat.push_back(kat);
break;
case ']' : x=stos_x.back();
y=stos_y.back();
kat=stos_kat.back();
stos_x.pop_back();
stos_y.pop_back();
stos_kat.pop_back();
Image1->Canvas->MoveTo(x,y);
break;
default : break;
}
}
//---------------------------------------------------------------------------
//gotowe przyklady
void __fastcall TForm1::ComboBox1Change(TObject *Sender)
{
switch (ComboBox1->ItemIndex)
{
case 0: //trojkat Sierpinskiego
Memo1->Text="F+F+F";
Memo1->Lines->Add("F: F+F-F-F+F");
LabeledEdit1->Text="120";
LabeledEdit2->Text="5";
LabeledEdit3->Text="5";
startX->Text = 120;
startY->Text = 250;
break;
case 1: //platek sniegu Kocha
Memo1->Text="F++F++F";
Memo1->Lines->Add("F: F-F++F-F");
LabeledEdit1->Text="60";
LabeledEdit2->Text="1";
LabeledEdit3->Text="5";
startX->Text = 75;
startY->Text = 300;
break;
case 2: //krzywa Kocha 1
Memo1->Text="F";
Memo1->Lines->Add("F: F+F--F+F");
LabeledEdit1->Text="60";
LabeledEdit2->Text="1";
LabeledEdit3->Text="5";
startX->Text = 75;
startY->Text = 300;
break;
case 3: //krzywa Kocha 2
Memo1->Text="F+F+F+F";
Memo1->Lines->Add("F: FF+F+F+F+F+F-F");
LabeledEdit1->Text="90";
LabeledEdit2->Text="1";
LabeledEdit3->Text="4";
startX->Text = 250;
startY->Text = 300;
break;
case 4: //krzywa Kocha 3
Memo1->Text="F+F+F+F";
Memo1->Lines->Add("F: FF+F++F+F");
LabeledEdit1->Text="90";
LabeledEdit2->Text="0,8";
LabeledEdit3->Text="5";
startX->Text = 100;
startY->Text = 300;
break;
case 5: //krzywa Kocha 4
Memo1->Text="F+F+F+F";
Memo1->Lines->Add("F: FF+F+F+F+FF");
LabeledEdit1->Text="90";
LabeledEdit2->Text="2";
LabeledEdit3->Text="4";
startX->Text = 100;
startY->Text = 300;
break;
case 6: //krzywa Hilberta
Memo1->Text="X";
Memo1->Lines->Add("X: -YF+XFX+FY-");
Memo1->Lines->Add("Y: +XF-YFY-FX+");
LabeledEdit1->Text="90";
LabeledEdit2->Text="3";
LabeledEdit3->Text="5";
startX->Text = 150;
startY->Text = 200;
break;
case 7: //krzywa Peano
Memo1->Text="X";
Memo1->Lines->Add("X: XFYFX+F+YFXFY-F-XFYFX");
Memo1->Lines->Add("Y: YFXFY-F-XFYFX+F+YFXFY");
LabeledEdit1->Text="90";
LabeledEdit2->Text="2";
LabeledEdit3->Text="4";
startX->Text = 120;
startY->Text = 250;
break;
case 8: //krzywa Moor'a
Memo1->Text="LFL+F+LFL";
Memo1->Lines->Add("L: -RF+LFL+FR-");
Memo1->Lines->Add("R: +LF-RFR-FL+");
LabeledEdit1->Text="90";
LabeledEdit2->Text="3";
LabeledEdit3->Text="5";
startX->Text = 100;
startY->Text = 230;
break;
case 9: //Smoka Heighway'a
Memo1->Text="Fl";
Memo1->Lines->Add("l: l+rF+");
Memo1->Lines->Add("r: -Fl-r");
LabeledEdit1->Text="90";
LabeledEdit2->Text="1";
LabeledEdit3->Text="13";
startX->Text = 200;
startY->Text = 230;
break;
case 10: //Smok Levy'ego
Memo1->Text="F";
Memo1->Lines->Add("F: +F--F+");
LabeledEdit1->Text="45";
LabeledEdit2->Text="1";
LabeledEdit3->Text="13";
startX->Text = 170;
startY->Text = 230;
break;
case 11: //spirala
Memo1->Text="AAAA";
Memo1->Lines->Add("A: X+X+X+X+X+X+");
Memo1->Lines->Add("X: [F+F+F+F[---X-Y]+++++F++++++++F-F-F-F]");
Memo1->Lines->Add("Y: [F+F+F+F[---Y]+++++F++++++++F-F-F-F]");
LabeledEdit1->Text="15";
LabeledEdit2->Text="6";
LabeledEdit3->Text="6";
startX->Text = 200;
startY->Text = 250;
break;
case 12: //pentadendryt
Memo1->Text="F";
Memo1->Lines->Add("F: F+F-F--F+F+F");
LabeledEdit1->Text="72";
LabeledEdit2->Text="3";
LabeledEdit3->Text="4";
startX->Text = 120;
startY->Text = 150;
break;
case 13: //drzewko 1
Memo1->Text="F";
Memo1->Lines->Add("F: F[+F]F[-F]F");
LabeledEdit1->Text="25,7";
LabeledEdit2->Text="2";
LabeledEdit3->Text="5";
startX->Text = 50;
startY->Text = 100;
break;
case 14: //drzewko 2
Memo1->Text="----F";
Memo1->Lines->Add("F: FF+[+F-F-F]-[-F+F+F]");
LabeledEdit1->Text="22,5";
LabeledEdit2->Text="3";
LabeledEdit3->Text="4";
startX->Text = 150;
startY->Text = 200;
break;
case 15: //drzewko 3
Memo1->Text="X";
Memo1->Lines->Add("X: F[+X]F[-X]+X");
Memo1->Lines->Add("F: FF");
LabeledEdit1->Text="20";
LabeledEdit2->Text="1";
LabeledEdit3->Text="7";
startX->Text = 150;
startY->Text = 200;
break;
}
}
//---------------------------------------------------------------------------

