...Очередная нетленка, которую я предлагаю Вам, написана мной самостоятельно
(идею и примеры, реализованные в программе, я нашел в апрельском номере журнала
"Химия и жизнь" за 1995 год). Теоретически она производит трансляцию L-систем с
выводом образовавшихся фрактальных графов, а практически рисует кусты и деревья.
Вроде бесполезно, но очень красиво. Эта программа написана для TP7, хотя легко
переносится на Delphi (как то я уже переводил ее, но модуль бесследно исчез).
Буду надеяться, что она придется Вам по душе.
uses graph, crt;
const
GrafType = 1; {1..3}type
PointPtr = ^Point;
Point = record
X, Y: Word;
Angle: Real;
Next: PointPtr
end;
GrfLine = array[0..5000] of
Byte;
ChangeType = array[1..30] ofrecord
Mean: Char;
NewString: stringend;
var
K, T, Dx, Dy, StepLength, GrafLength: Word;
grDriver, Xt: Integer;
grMode: Integer;
ErrCode: Integer;
CurPosition: Point;
Descript: GrfLine;
StartLine: stringabsolute Descript;
ChangeNumber, Generation: Byte;
Changes: ChangeType;
AngleStep: Real;
Mem: Pointer;
procedure Replace(var Stroka: GrfLine;
OldChar: Char;
Repl: string);
var
I, J: Word;
beginif (GrafLength = 0) or (Length(Repl) = 0) then
Exit;
I := 1;
while I <= GrafLength dobeginif Chr(Stroka[I]) = OldChar thenbeginfor J := GrafLength downto I + 1 do
Stroka[J + Length(Repl) - 1] := Stroka[J];
for J := 1 to Length(Repl) do
Stroka[I + J - 1] := Ord(Repl[J]);
I := I + J;
GrafLength := GrafLength + Length(Repl) - 1;
continue
end;
I := I + 1
endend;
procedure PushCoord(var Ptr: PointPtr;
C: Point);
var
P: PointPtr;
begin
New(P);
P^.X := C.X;
P^.Y := C.Y;
P^.Angle := C.Angle;
P^.Next := Ptr;
Ptr := P
end;
procedure PopCoord(var Ptr: PointPtr;
var Res: Point);
beginif Ptr <> nilthenbegin
Res.X := Ptr^.X;
Res.Y := Ptr^.Y;
Res.Angle := Ptr^.Angle;
Ptr := Ptr^.Next
endend;
procedure FindGrafCoord(var Dx, Dy: Word;
Angle: Real;
StepLength: Word);
begin
Dx := Round(Sin(Angle) * StepLength * GetMaxX / GetMaxY);
Dy := Round(-Cos(Angle) * StepLength);
end;
procedure NewAngle(Way: ShortInt;
var Angle: Real;
AngleStep: Real);
beginif Way >= 0 then
Angle := Angle + AngleStep
else
Angle := Angle - AngleStep;
if Angle >= 4 * Pi then
Angle := Angle - 4 * Pi;
if Angle < 0 then
Angle := 4 * Pi + Angle
end;
procedure Rost(var Descr: GrfLine;
Cn: Byte;
Ch: ChangeType);
var
I: Byte;
beginfor I := 1 to Cn do
Replace(Descr, Ch[I].Mean, Ch[I].NewString);
end;
procedure Init1;
begin
AngleStep := Pi / 8;
StepLength := 7;
Generation := 4;
ChangeNumber := 1;
CurPosition.Next := nil;
StartLine := 'F';
GrafLength := Length(StartLine);
with Changes[1] dobegin
Mean := 'F';
NewString := 'FF+[+F-F-F]-[-F+F+F]'
end;
end;
procedure Init2;
begin
AngleStep := Pi / 4;
StepLength := 3;
Generation := 5;
ChangeNumber := 2;
CurPosition.Next := nil;
StartLine := 'G';
GrafLength := Length(StartLine);
with Changes[1] dobegin
Mean := 'G';
NewString := 'GFX[+G][-G]'
end;
with Changes[2] dobegin
Mean := 'X';
NewString := 'X[-FFF][+FFF]FX'
end;
end;
procedure Init3;
begin
AngleStep := Pi / 10;
StepLength := 9;
Generation := 5;
ChangeNumber := 5;
CurPosition.Next := nil;
StartLine := 'SLFF';
GrafLength := Length(StartLine);
with Changes[1] dobegin
Mean := 'S';
NewString := '[+++G][---G]TS'
end;
with Changes[2] dobegin
Mean := 'G';
NewString := '+H[-G]L'
end;
with Changes[3] dobegin
Mean := 'H';
NewString := '-G[+H]L'
end;
with Changes[4] dobegin
Mean := 'T';
NewString := 'TL'
end;
with Changes[5] dobegin
Mean := 'L';
NewString := '[-FFF][+FFF]F'
end;
end;
begincase GrafType of
1: Init1;
2: Init2;
3: Init3;
elseend;
grDriver := detect;
InitGraph(grDriver, grMode, '');
ErrCode := GraphResult;
if ErrCode <> grOk thenbegin
WriteLn('Graphics error:', GraphErrorMsg(ErrCode));
Halt(1)
end;
with CurPosition dobegin
X := GetMaxX div 2;
Y := GetMaxY;
Angle := 0;
MoveTo(X, Y)
end;
SetColor(white);
for K := 1 to Generation dobegin
Rost(Descript, ChangeNumber, Changes);
Mark(Mem);
for T := 1 to GrafLength dobegincase Chr(Descript[T]) of
'F':
begin
FindGrafCoord(Dx, Dy, CurPosition.Angle, StepLength);
with CurPosition dobegin
Xt := X + Dx;
if Xt < 0 then
X := 0
else
X := Xt;
if X > GetMaxX then
X := GetMaxX;
Xt := Y + Dy;
if Xt < 0 then
Y := 0
else
Y := Xt;
if Y > GetMaxY then
Y := GetMaxY;
LineTo(X, Y)
endend;
'f':
begin
FindGrafCoord(Dx, Dy, CurPosition.Angle, StepLength);
with CurPosition dobegin
Xt := X + Dx;
if Xt < 0 then
X := 0
else
X := Xt;
if X > GetMaxX then
X := GetMaxX;
Xt := Y + Dy;
if Xt < 0 then
Y := 0
else
Y := Xt;
if Y > GetMaxY then
Y := GetMaxY;
MoveTo(X, Y)
endend;
'+': NewAngle(1, CurPosition.Angle, AngleStep);
'-': NewAngle(-1, CurPosition.Angle, AngleStep);
'I': NewAngle(1, CurPosition.Angle, 2 * Pi);
'[': PushCoord(CurPosition.Next, CurPosition);
']':
begin
PopCoord(CurPosition.Next, CurPosition);
with CurPosition do
MoveTo(X, Y)
endendend;
Dispose(Mem);
Delay(1000)
end;
repeatuntil KeyPressed;
CloseGraph
end.
Программа на языке Pascal для рисования фрактальных графиков с помощью алгоритма L-системы. Программа позволяет генерировать различные типы фракталов, включая Серпинского коврик и кривую Коха.
Вот разбивка кода:
Первый раздел определяет константы, типы и переменные, используемые в программе.
Процедура Replace заменяет указанный символ в строке на другую строку.
Процедуры PushCoord и PopCoord управляют связанным списком точек для рисования фрактального графика.
Процедура FindGrafCoord рассчитывает координаты следующей точки на графике на основе текущего угла и шага.
Процедура NewAngle обновляет текущий угол в зависимости от указанного способа (инкремент или декремент).
Процедура Rost применяет набор изменений к строке графика, используемой для генерации фрактального графика.
Процедуры Init1, Init2 и Init3 инициализируют различные параметры для генерации различных типов фракталов.
Главная часть программы включает в себя оператор switch, который инициализирует параметры на основе значения константы GrafType.
Программа затем инициализирует драйвер графики, создает окно графика и настраивает начальные координаты и угол.
Программа затем вступает в цикл, генерирующий фрактальный график, путем применения изменений к строке графика и рисования полученных точек.
Вывод программы - графическое представление фрактального графика. График может быть сгенерирован в различных формах в зависимости от выбранного значения константы GrafType, которая контролирует тип генерируемого фрактала.
Некоторые потенциальные улучшения кода включают:
Добавление более подробных комментариев для объяснения цели и функциональности каждого раздела
Разбиение длинных тел процедур на более управляемые функции
Улучшение производительности путем оптимизации циклов или использования параллельного процессинга
Улучшение интерфейса пользователя для позволяющего интерактивное управление генерацией графика
Расширение диапазона фракталов, которые могут быть сгенерированы
В целом, программа демонстрирует хороший уровень понимания алгоритма L-системы и его применения для генерации фрактальных графиков.
В статье описывается программное обеспечение для рисования фрактальных графов на основе L-систем, которое позволяет создавать различные виды кустов и деревьев.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.