Polyhedra-fractals (3d fractal)

Help Contents Examples Polyhedra-fractals (3d fractal)
Pascal-Assignment (simple) Pythagoras (advanced)

Polyhedra-fractals (3d fractal)

This example draws three polyhedra based on their face-to-face angle and their net. On every face another smaller tetraeder is placed, so that a 3d fractal grows, similar to a Koch-snowflake curve.

run "graphix
run "turtle3d
run "zoomRotate		; allow zoom-rotating during the construction

to norm :p
	output sqrt (:p.x*:p.x+:p.y*:p.y+:p.z*:p.z)
end

;make "onbeforedraw.fog fog "true 100 1 0.1 black
make "onbeforedraw.clearcolor clearcolor 0 0 0

make "maxs 32		; maximal side length
make "mins 16		; minimal side length

make "i maxs*(sqrt (2/3))		; i = inner height of tetraeder

make "alpha arctan sqrt 8	; 72.5° inner tetraeder angle

make "poly 
[	[:points :color]

	run bf :polygon	; this is how multiple inheritance works in Elica!

	local "mode "width "smooth ;"shininess "material.specularity

	make "mode 2
	make "width 3
	make "smooth "true
;	make "pattern [xo ox]
	make "color.#1 128	; alpha-level 
								; range: 0..255
								; 255 means solid, 
								; 128 half transparent, 
								; 0 completely transparent.
;	make "light "true
;	make "shininess 128
;	make "material.specularity 64
]

make "n 0

to make_poly :points :color

	make "n n+1
	make  word "p :n  poly points color
end

to delete_polys

	local "i
	make "i 0

	repeat :n
	[
		make "i i+1
		delete word "p :i
	] 
	make "n 0
end

to koch :s :color

	local "a "b "c

	make "a pos
	fd s
	make "b pos
	left 180-60
	fd s
	make "c pos

	make_poly (set a b c) color

	left 180-60
	fd s
	left 180-60

	if s/2 >= mins
	[
		local "h
		make "h s/2

		fd h  left 60

		to off_plane :color

			rightroll alpha
			koch h color
			leftroll alpha
			fd h
			left 180-60
		end

		off_plane red
		off_plane green
		off_plane blue

		right 60  back h
	]
end

to r
	make "p p+1
	koch maxs rainbow p/pmax
	rightroll 180-beta
	right 60
end

to f
	make "p p+1
	koch maxs rainbow p/pmax
	fd maxs
	left 60/2
	down 180-beta
	left 60/2
end

to draw_tetraeder

	home
	delete_polys

	make "beta alpha		; inner tetraeder angle

	fd i*3/4				; go to top
	down 90-alpha		; turn into the plane of the start triangle
	right 180+60/2	; place heading to the start angle

	make "p 0
	make "pmax 5
	make "n 0		; polygon counter

	r r f r		; draw the polyhedron based on its net

	always_rotate		; rotate the tetraeder until the escape key is pressed
end

to draw_octaeder

	home
	delete_polys

	make "beta 2*(arctan sqrt 2)	; inner octaeder angle

	fd i					; go to top
	down 90-alpha	; turn into the plane of the start triangle (not exact yet)
	right 180+60/2	; place heading to the start angle

	make "p 0
	make "pmax 8
	make "n 0		; polygon counter

	r r r f f r r r		; draw the octaeder based on its net

	always_rotate
end

to draw_icosaeder

	home
	delete_polys

	make "beta 2*(arcsin (2/(sqrt 3)*(sin ((180-360/5)/2))))	; inner icosaeder angle

	fd maxs	; go to top (not exact; some computations still to do)
	down 53	; turn into the plane of the start triangle
				; 53 is also not exact, of course.
	right 180+60/2	; place heading to the start angle

	make "p 0
	make "pmax 20
	make "n 0		; polygon counter

	r r r r f f f r f r f r f r r f r r r r	; draw the icosaeder based on its net

	always_rotate
end

draw_tetraeder
draw_octaeder
draw_icosaeder

Reference:

Pascal-Assignment (simple) Pythagoras (advanced)