Fractals
A fractal is a complex geometric shape that can be split into parts, each of which is a reduced-scale copy of the whole. This property is known as self-similarity.
dragon.gle
dragon.gle
! Example with the dragon curve.
! Author: Francois Tonneau
size 11 8
set color cadetblue lwidth 0.03
dist = 0.1
angle = 0
sub expansion letter$
if letter$ = "X" then
return "X+YF+"
else &
if letter$ = "Y" then
return "-FX-Y"
else
return letter$
end if
end sub
sub goforward
rline dist*cos(angle) dist*sin(angle)
end sub
sub turnleft
angle = angle + pi/2
end sub
sub turnright
angle = angle - pi/2
end sub
sub takeaction letter$
if letter$ = "F" then
goforward
else &
if letter$ = "+" then
turnleft
else &
if letter$ = "-" then
turnright
end if
end sub
sub growdragon times
local stage
for stage = 1 to times
local adult$ = ""
local pos, code$
for pos = 1 to len(dragon$)
code$ = seg$(dragon$, pos, pos)
adult$ = adult$ + expansion(code$)
next pos
dragon$ = adult$
next stage
end sub
sub drawdragon
local pos, code$
for pos = 1 to len(dragon$)
code$ = seg$(dragon$, pos, pos)
takeaction(code$)
next pos
end sub
dragon$ = "FX"
growdragon times 12
amove 8 3
drawdragon
koch.gle
koch.gle
size 10 10
sub koch x1 y1 x2 y2 d
if d = 0 then
amove x1 y1
aline x2 y2
else
local x13 = x1+(x2-x1)/3
local y13 = y1+(y2-y1)/3
local x23 = x1+(x2-x1)*2/3
local y23 = y1+(y2-y1)*2/3
local x_c = x1+0.5*(x2-x1)+(y2-y1)/sqrt(12)
local y_c = y1+0.5*(y2-y1)-(x2-x1)/sqrt(12)
koch x1 y1 x13 y13 d-1
koch x13 y13 x_c y_c d-1
koch x_c y_c x23 y23 d-1
koch x23 y23 x2 y2 d-1
end if
end sub
sub kochflake wd depth
local x0 = pagewidth()/2-wd
local y0 = pageheight()/2-wd*tan(torad(30))
local x1 = x0+wd
local y1 = y0+2*wd*sin(torad(60))
local x2 = x0+wd*2
koch x0 y0 x2 y0 depth
koch x1 y1 x0 y0 depth
koch x2 y0 x1 y1 depth
end sub
for i = 1 to 4
set color rgb(0,0,i/5)
kochflake 0.4*(1.8^i) i
next i
lindenmayer.gle
lindenmayer.gle
! Example of Lindenmayer system.
! Author: Francois Tonneau
size 18 15
set color #afbb63 cap round
dist = 0.1
angle = torad(50)
turn = torad(25)
mark = 0
sub expansion letter$
if letter$ = "F" then
return "FF"
else &
if letter$ = "X" then
return "F[+X][X]F[+X]-FX"
else
return letter$
end if
end sub
sub goforward
rline dist*cos(angle) dist*sin(angle)
end sub
sub turnleft
angle = angle + turn
end sub
sub turnright
angle = angle - turn
end sub
! We abuse named points to simulate push() and pop() functions on a stack; the
! 'mark' variable is increased or decreased as the depth of the stack varies.
sub takenote
mark = mark + 1
local placetag$ = eval("place_" + mark)
save placetag$
gsave
local angletag$ = eval("angle_" + mark)
amove angle 0
save angletag$
grestore
end sub
sub comeback
local placetag$ = eval("place_" + mark)
amove ptx(placetag$.cc) pty(placetag$.cc)
local angletag$ = eval("angle_" + mark)
angle = ptx(angletag$.cc)
mark = mark - 1
end sub
sub takeaction letter$
if letter$ = "F" then
goforward
else &
if letter$ = "+" then
turnleft
else &
if letter$ = "-" then
turnright
else &
if letter$ = "[" then
takenote
else &
if letter$ = "]" then
comeback
end if
end sub
sub growplant times
local stage
for stage = 1 to times
local adult$ = ""
local pos, code$
for pos = 1 to len(plant$)
code$ = seg$(plant$, pos, pos)
adult$ = adult$ + expansion(code$)
next pos
plant$ = adult$
next stage
end sub
sub drawplant
local pos, code$
for pos = 1 to len(plant$)
code$ = seg$(plant$, pos, pos)
takeaction(code$)
next pos
end sub
plant$ = "X"
growplant times 6
amove 1 1
drawplant
mandelbrot.gle
mandelbrot.gle mandelbrot.zip zip file contains all files for this figure.
mandelbrot.gle
! Example of Mandelbrot set.
! Author: Francois Tonneau
size 18 16
! ------------------------------
! Set plot resolution.
! ------------------------------
resolution = 1250 ! Use a value < 1000 if plotting takes too long!
itermax = 30
worth = 4
! ------------------------------
! Cover background with default hue.
! ------------------------------
! We overflow borders by 2 cm to cover possible white margins.
amove -1 -1
box pagewidth()+2 pageheight()+2 fill rgb255(38, 44, 64)
! ------------------------------
! Define plot parameters.
! ------------------------------
xmax = pagewidth()
ymax = pageheight()
dx = xmax/resolution
dy = ymax/resolution
ulow = -2.20
uhigh = 0.80
vlow = -1.45
vhigh = 1.45
uspan = uhigh - ulow
vspan = vhigh - vlow
declare sub spot u0 v0
declare sub color iter
declare sub paint hue$
! ------------------------------
! Cover the plot surface.
! ------------------------------
print "This may take a while..."
for x = 0 to xmax step dx
for y = 0 to ymax step dy
amove x y
u0 = (x/xmax * uspan) + ulow
v0 = (y/ymax * vspan) + vlow
spot(u0, v0)
next y
next x
print "Preparing output..."
! ------------------------------
! Implement coloring utilities.
! ------------------------------
sub spot u0 v0
local u = 0.0
local v = 0.0
local iter = 0
local utemp
while ((u*u + v*v <= 4) and (iter < itermax))
utemp = u*u - v*v + u0
v = 2*u*v + v0
u = utemp
iter = iter + 1
next
if iter = itermax then
paint black
else
! To speed up the code, do nothing when iter < worth, leaving the
! default background show through.
if iter >= worth then paint color(iter)
end if
end sub
sub color iter
local t = (iter - worth)/(itermax - worth)
!
local r0 = 45
local g0 = 52
local b0 = 72
!
local r1 = 190
local g1 = 65
local b1 = 50
!
local r2 = 220
local g2 = 220
local b2 = 180
!
local r, g, b
if t <= 0.50 then
r = (1 - t) * r0 + t * r1
g = (1 - t) * g0 + t * g1
b = (1 - t) * b0 + t * b1
else
r = r2
g = g2
b = b2
end if
return rgb255(r, g, b)
end sub
sub paint hue$
set color hue$
box dx dy fill hue$
end sub
pythagoras.gle
pythagoras.gle
! Example of Pythagoras tree.
! Author: Francois Tonneau
! This is a slight modification of the Pythagoras tree example available on GLE
! 4.2.5. The idea for edge coloring comes from Timo Bingmann:
! https://panthema.net/2013/0627-TikZ-Pythagoras-Tree/
size 32 22
small = 3
medium = 4
large = sqrt(small^2 + medium^2)
set lwidth 0.1
sub growtree times
local rchan = rnd(0.5)
local gchan = rnd(0.8)
local bchan = rnd(0.6)
set color rgb(rchan, gchan, bchan)
box large large
if times > 0 then
begin translate 0 large
begin rotate todeg(acos(medium/large))
begin scale medium/large medium/large
growtree times-1
end scale
end rotate
end translate
begin translate large large
begin rotate todeg(-acos(small/large))
begin scale small/large small/large
begin translate -large 0
growtree times-1
end translate
end scale
end rotate
end translate
end if
end sub
begin translate 16 0
growtree times 11
end translate
pythagorean.gle
pythagorean.gle
size 32 22
a = 3; b = 4; c = sqrt(a^2+b^2)
sub pythagorean n
local red = (34+n*92)/(n+1)
local green = (139+n*64)/(n+1)
local blue = (34+n*51)/(n+1)
box c c fill rgb255(red,green,blue)
if n = 0 then return
begin translate c c
begin rotate todeg(-acos(a/c))
begin scale a/c a/c
begin translate -c 0
pythagorean n-1
end translate
end scale
end rotate
end translate
begin translate 0 c
begin rotate todeg(acos(b/c))
begin scale b/c b/c
pythagorean n-1
end scale
end rotate
end translate
end sub
begin translate 16 0
pythagorean 10
end translate
recursiontree.gle
recursiontree.gle
size 8 8
! Based on "C" code by Lode Vandevenne
! http://www.student.kuleuven.ac.be/~m0216922/CG/
set cap round
maxRecursions = 8 ! never make this too big or it'll take forever
angle = 0.2 * pi ! angle in radians
shrink = 1.8 ! relative size of new branches
! Now follows the recursion function, a function that only draws a single line and calls
! itself a few times, but results in a huge tree!
sub recursion posX posY dirX dirY bsize n
! Here's the part that draws the line. The line is drawn from (posX, posY) to (posX+dirX,
! posY+dirY). So the position and direction of the line is given as a vector, instead of
! a begin point, an angle and a size, because direction vectors are much easier to work
! with. The size parameter itself isn't used to draw the line directly, it's only needed
! later to calculate the direction vector of the next branches. If the maximum number of
! recursions is reached, the function returns immediately after drawing the line, without
! calling itself again.
local posX2 = posX + bsize * dirX
local posY2 = posY + bsize * dirY
if n > 5 then
set color forestgreen
else
set color rgb255(128, 96, 64)
end if
set lwidth 0.2/(n+1)+0.005
amove posX pageheight()-posY
aline posX2 pageheight()-posY2
if n < maxRecursions then
! And in the second part of the function, the new position of the new branches is
! calculated as the endpoint of the previous branch, and the new direction vector for
! the new branches is calculated out of the size and current direction of the current
! branch. The new branches are rotated with the angle, the sine and cosine formulas are
! actually the calculation of the rotation matrix. Then the recursion function is called
! again with the new branch as its parameters. This is done twice: once for a branch
! rotated to the right, and then for a branch rotated to the left.
dirX2 = cos(angle) * dirX + sin(angle) * dirY
dirY2 = -sin(angle) * dirX + cos(angle) * dirY
recursion posX2 posY2 dirX2 dirY2 bsize/shrink n+1
dirX2 = cos(-angle) * dirX + sin(-angle) * dirY
dirY2 = -sin(-angle) * dirX + cos(-angle) * dirY
recursion posX2 posY2 dirX2 dirY2 bsize/shrink n+1
end if
end sub
! The main program doesn't do much more than calling the recursive function.
! The value "h/2.3" in the parameters of the recursion function is the initial
! length of the first branch (the stem). The coordinates are the begin
! point and direction vector of the first branch.
w = pagewidth()
h = pageheight()
recursion w/2 h-0.1 0 -1 h/2.3 0
sierpinski.gle
sierpinski.gle
size 10 8.75
wd = 4.75; ad = 0.2
set lwidth 0.01 cap round
sub a_line x0 y0 x1 y1
amove x0 y0
aline x1 y1
end sub
sub sierpinski x_left x_right y_bot y_top d
if d > 0 then
set color rgb(1/(d+ad),0,0)
local y_c = (y_bot+y_top)/2 ! middle y coordinate
local x_c = (x_left+x_right)/2 ! middle x coordinate
local x_1 = (x_left+x_c)/2 ! 1/3 x coordinate
local x_2 = (x_c+x_right)/2 ! 2/3 x coordinate
a_line x_c y_bot x_1 y_c
a_line x_1 y_c x_2 y_c
a_line x_2 y_c x_c y_bot
sierpinski x_left x_c y_bot y_c d-1 ! lower left triangle
sierpinski x_c x_right y_bot y_c d-1 ! lower right triangle
sierpinski x_1 x_2 y_c y_top d-1 ! top triangle
end if
end sub
x_left = pagewidth()/2 - wd
y_bot = pageheight()/2 - wd*sin(torad(60))
y_top = y_bot + 2*wd*sin(torad(60))
x_right = x_left + wd*2
x_c = x_left + wd
a_line x_left y_bot x_c y_top
a_line x_c y_top x_right y_bot
a_line x_right y_bot x_left y_bot
sierpinski x_left x_right y_bot y_top 7
tree.gle
tree.gle
! Example of tree-like fractal.
! Author: Francois Tonneau
! This is a slight modification of the recursion-tree example available on GLE
! 4.2.5. We use the GLE rotation command instead of computing coordinates
! manually.
size 8 8
set lwidth 0.03 cap round
root = 3
maxiters = 10
maxwhite = maxiters + 3
turn = 20
shrinkage = 0.56
sub fork trunk iteration
if iteration <= maxiters then
set color iteration/maxwhite
rline 0 trunk
local branch = trunk * shrinkage
begin rotate turn
fork branch iteration+1
end rotate
begin rotate -turn
fork branch iteration+1
end rotate
else
rmove 0 0.1+rnd(0.3)
circle 0.03 fill rosybrown
end if
end sub
amove pagewidth()/2 0
fork root iteration 1