### Bookstore

 Computer Math and Games in Pascal (preview) Lazarus Handbook

### Author Topic: Fibonacci Word Fractal  (Read 924 times)

#### Boleeman

• Hero Member
• Posts: 569
##### Fibonacci Word Fractal
« on: June 07, 2024, 12:04:35 pm »
A Fibonacci Word Fractal.

When the N value is low you will need to increase the step size, otherwise the curve is drawn too small to be seen correctly.

Wondered how to make the canvas oversized to be able to see the fractal at larger recursion levels?

(Possibly a Zoom control, BgraVirtualScreen ?)

As shown in the 2nd attached picture, the fractal curve is only partly seen. How to see that whole curve?
« Last Edit: June 08, 2024, 01:26:05 am by Boleeman »

#### Handoko

• Hero Member
• Posts: 5248
• My goal: build my own game engine using Lazarus
##### Re: Fibonacci Word Fractal
« Reply #1 on: June 16, 2024, 11:08:06 pm »
(Possibly a Zoom control, BgraVirtualScreen ?)

Done.

I quickly rewrite your code tested on Linux only, it may contain bugs.

Code: Pascal  [Select][+][-]
1. unit Unit1;
2.
3. {\$mode objfpc}{\$H+}
4.
5. interface
6.
7. uses
8.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls, Spin,
9.   StdCtrls, ComCtrls, OpenGLContext, GL, Math;
10.
11. type
12.
13.   { TForm1 }
14.
15.   TForm1 = class(TForm)
16.     cbBackcolor: TColorButton;
17.     cbLinecolor: TColorButton;
18.     Label1: TLabel;
19.     Label2: TLabel;
20.     Label3: TLabel;
21.     Label4: TLabel;
22.     Label5: TLabel;
23.     OpenGLControl1: TOpenGLControl;
24.     Panel1: TPanel;
25.     seLinewidth: TSpinEdit;
26.     seNvalue: TSpinEdit;
27.     seStepSize: TSpinEdit;
28.     TrackBar1: TTrackBar;
29.     procedure FormCreate(Sender: TObject);
30.     procedure ControlChange(Sender: TObject);
31.     procedure OpenGLControl1Resize(Sender: TObject);
32.   private
33.     glTextureID: array[0..0] of GLuint; // OpenGL texture
34.     procedure DoDraw;
35.     procedure DrawWordFractal(n: Integer; g: TCanvas; x, y, dx, dy: integer);
36.     function GetWordFractal(n: Integer): string;
37.   public
38.
39.   end;
40.
41. var
42.   Form1: TForm1;
43.
44. implementation
45.
46. {\$R *.lfm}
47.
48. { TForm1 }
49.
50. procedure TForm1.FormCreate(Sender: TObject);
51. begin
52.
53.   Panel1.Align                      := alLeft;
54.   OpenGLControl1.Align              := alClient;
55.   OpenGLControl1.AutoResizeViewport := True;
56.
57.   seNvalue.MinValue                 := 1;
58.   seNvalue.MaxValue                 := 30;
59.   seNvalue.Value                    := 20;
60.
61.   seStepSize.MinValue               := 1;
62.   seStepSize.MaxValue               := 20;
63.   seStepSize.Value                  := 3;
64.
65.   seLinewidth.MinValue              := 1;
66.   seLinewidth.MaxValue              := 10;
67.   seLinewidth.Value                 := 2;
68.
69.   cbLinecolor.ButtonColor           := clBlack;
70.   cbBackcolor.ButtonColor           := clWhite;
71.
72. end;
73.
74. procedure TForm1.ControlChange(Sender: TObject);
75. begin
76.   DoDraw;
77. end;
78.
79. procedure TForm1.OpenGLControl1Resize(Sender: TObject);
80. const
81.   ZNear = 0.1;
82.   ZFar  = 100;
83. var
84.   X, Y: GLdouble;
85. begin
86.   glViewport(0, 0, OpenGLControl1.Width, OpenGLControl1.Height);
87.   glMatrixMode(GL_PROJECTION);
89.   Y := Tan(40 * Pi / 360) * ZNear;
90.   X := Y * OpenGLControl1.Width / OpenGLControl1.Height;
91.   glFrustum(-X, X, -Y, Y, ZNear, ZFar);
92.   glMatrixMode(GL_MODELVIEW);
94.   DoDraw;
95. end;
96.
97. procedure TForm1.DoDraw;
98. const
99.   PictureSize = 1000;
100. var
101.   Bitmap: TBitmap;
102. begin
103.
104.   Bitmap        := TBitmap.Create;
105.   Bitmap.Height := PictureSize;
106.   Bitmap.Width  := PictureSize;
107.   Bitmap.Clear;
108.   DrawWordFractal(seNvalue.Value, Bitmap.Canvas, 20, Bitmap.Height - 20, seStepSize.Value, 0);
109.
110.   OpenGLControl1.MakeCurrent;
111.   glGenTextures(1, glTextureID);
112.   glBindTexture(GL_TEXTURE_2D, glTextureID[0]);
113.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
114.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
115.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
116.   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
117.   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, PictureSize, PictureSize, 0, GL_RGBA,
118.     GL_UNSIGNED_BYTE, Bitmap.RawImage.Data);
119.   glBindTexture(GL_TEXTURE_2D, glTextureID[0]);
120.   Bitmap.Free;
121.
122.   glEnable(GL_TEXTURE_2D);
123.   glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
125.   glTranslatef(0, 0, -TrackBar1.Position/2);
127.     glTexCoord2f(0, 1); glVertex3f(-1, -1, 0);
128.     glTexCoord2f(1, 1); glVertex3f( 1, -1, 0);
129.     glTexCoord2f(1, 0); glVertex3f( 1,  1, 0);
130.     glTexCoord2f(0, 0); glVertex3f(-1,  1, 0);
131.   glEnd;
132.   OpenGLControl1.SwapBuffers;
133.   glDeleteTextures(1, glTextureID);
134.
135. end;
136.
137. function TForm1.GetWordFractal(n: Integer): string;
138. var
139.   f1, f2, tmp: string;
140.   i: Integer;
141. begin
142.   case n of
143.     0: Result := '';
144.     1: Result := '1';
145.   else
146.     begin
147.       f1 := '1';
148.       f2 := '0';
149.       for i := n - 2 downto 1 do
150.       begin
151.         tmp := f2;
152.         f2 := f2 + f1;
153.         f1 := tmp;
154.       end;
155.       Result := f2;
156.     end;
157.   end;
158. end;
159.
160. procedure TForm1.DrawWordFractal(n: Integer; g: TCanvas; x, y, dx, dy: integer);
161. var
162.   i, tx: Integer;
163.   wordFractal: string;
164. begin
165.   wordFractal := GetWordFractal(n);
166.   with g do
167.   begin
168.     Brush.Color := cbBackcolor.ButtonColor;
169.     FillRect(ClipRect);
170.     Pen.Color := cbLinecolor.ButtonColor;
171.     Pen.Width := seLinewidth.Value;
172.     MoveTo(x, y);
173.   end;
174.   for i := 1 to wordFractal.Length do
175.   begin
176.     g.LineTo(x + dx, y + dy);
177.     Inc(x, dx);
178.     Inc(y, dy);
179.     if wordFractal[i] = '0' then
180.     begin
181.       tx := dx;
182.       if Odd(i) then
183.       begin
184.         dx := dy;
185.         dy := -tx;
186.       end
187.       else
188.       begin
189.         dx := -dy;
190.         dy := tx;
191.       end;
192.     end;
193.   end;
194. end;
195.
196. end.

Because I used TOpenGLContext, you need to enable LazOpenGLContext package in your Lazarus by doing:
Lazarus main menu > Package > Install/Uninstall Packages > right panel, select: LazOpenGLContext 0.0.1 > Install selection > Save and rebuild IDE

Make sure your computer has VGA driver installed properly. For Linux users, you need to have libgl1-mesa-dev installed.

In the uses clause I added OpenGLContext, GL, Math (see line #9).  In Form.OnCreate event I added some lines, see line #53..55. For the OpenGL control to be able to do proportional resizing, I added the code for OpenGLControl1Resize event, see line #79.

If you want to change the picture size, see line #99. To change the zoom increment value, see line #125.

All the repaints now are handled by DoDraw, see line #97. It is done by doing the fractal drawing to a bitmap and then draw to bitmap's texture in the OpenGL control.

#### Boleeman

• Hero Member
• Posts: 569
##### Re: Fibonacci Word Fractal
« Reply #2 on: June 17, 2024, 08:15:18 am »
Thanks Handoko for your Linux version.

I wanted to do an install of Linux.

Wondered what type of Linux and version I should install that works reliably with Lazarus?

#### TRon

• Hero Member
• Posts: 2903
##### Re: Fibonacci Word Fractal
« Reply #3 on: June 17, 2024, 08:50:33 am »
Wondered what type of Linux and version I should install that works reliably with Lazarus?
Go with what looks like you are most comfortable with.

If you come from f.e. windows then there are special Linux distro's tailored for windows users (these attempt to try and make you feel at home).

I would personally advise to go with something debian based and for your dear life please stay away from wayland.

And whatever you do do not install Lazarus from your distro's package manager: do it manually or use fpcupdeluxe.

BTW: be advised that such question could potentially end up as a topic of its own so perhaps worth considering spending a separate thread for it.
« Last Edit: June 17, 2024, 09:00:54 am by TRon »

#### cdbc

• Hero Member
• Posts: 1355
##### Re: Fibonacci Word Fractal
« Reply #4 on: June 17, 2024, 09:08:59 am »
Hi
Quote
Wondered what type of Linux and version I should install that works reliably with Lazarus?
You should try and have a look at PCLinuxOS: https://www.pclinuxos.com/?page_id=180 It's an easy transit, when you come from windows. Even though it's a 'rolling release', it's a bit conservative e.g.: the distro will wait with Wayland, till it's matured a bit/lot and we've even got a Debian flavour, if you so wish. In the repo, we've got the latest release versions of software and e.g.: I'm running fpc trunk & laz 3.0, installed from "FpcUpDeluxe", in paralel
It's definately worth a try.
<Spoiler End>
Regards Benny
If it ain't broke, don't fix it
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 2.2.6 up until Jan 2024 from then on it's: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 3.0

#### TRon

• Hero Member
• Posts: 2903
##### Re: Fibonacci Word Fractal
« Reply #5 on: June 17, 2024, 09:16:18 am »
I forgot to mention something that Boleeman might be interested in and it is named ventoy which, after initial setup, allows you to copy-paste iso's to a flash-drive and which you can then pop into a USB port, boot and select which ISO you wish to run. Most Linux distribution provide a live mode CD/DVD iso so that you can test-drive a distribution.

#### Boleeman

• Hero Member
• Posts: 569
##### Re: Fibonacci Word Fractal
« Reply #6 on: June 17, 2024, 09:22:28 am »

Going to have a 2 week (teacher) break coming up soon so will start the install process then.