triFrac (3d)

Help Contents Examples triFrac (3d)
TriCircles (simple) Walker (advanced 3d)

triFrac (3d)



This example draws random landscape fractals. It is based on a famous triangle-dividing algorithm, which constructs a new point in the middle of every side, and varies its height randomly with a good scale.

It also demonstrates how array-like dynamically named variables can be used. Without arrays or this kludge the program wouldn`t be so easy.

run "graphix
;run "vector3d	; didn`t work like I wanted it
run "colors
run "fly			; allow flying around 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 80 80 160

make "maxs 256	; maximal side length
make "mins 32		; 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

	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 "multicolor "true
]

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 trifrac :A :B :C :h

	make "s.x A.x-B.x
	make "s.y 0
	make "s.z A.z-B.z
	make "s norm s

	if s >= mins
	[
		local "AB "BC "CA

		make "AB.x (A.x+B.x)/2
		make "AB.z (A.z+B.z)/2
		make "name (word "t. AB.x "'_' AB.z)
	;	print name
		if not exists? name
		[
			make :name (A.y+B.y)/2+(random h)-h/2
		]
		make "AB.y :(:name)

		make "BC.x (B.x+C.x)/2
		make "BC.z (B.z+C.z)/2
		make "name (word "t. BC.x "'_' BC.z)
		if not exists? name
		[
			make :name (B.y+C.y)/2+(random h)-h/2
		]
		make "BC.y :(:name)

		make "CA.x (C.x+A.x)/2
		make "CA.z (C.z+A.z)/2
		make "name (word "t. CA.x "'_' CA.z)
		if not exists? name
		[
			make :name (C.y+A.y)/2+(random h)-h/2
		]
		make "CA.y :(:name)

		trifrac A AB CA h*f
		trifrac B BC AB h*f
		trifrac C CA BC h*f
		trifrac AB BC CA h*f
	]
	[
		if (A.y>0) and (B.y>0) and (C.y>0)
		[
			make "A.color rgb_  4*A.y/maxs  0.4  2*A.y/maxs
			make "B.color rgb_  4*B.y/maxs  0.4  2*B.y/maxs
			make "C.color rgb_  4*C.y/maxs  0.4  2*C.y/maxs

			make_poly (set A B C) 0
		]
		[
			make "a A
			make "b B
			make "c C

			make "a.color rgb_  0.4+2*a.y/maxs  0.4+2*a.y/maxs  1+4*a.y/maxs
			make "b.color rgb_  0.4+2*b.y/maxs  0.4+2*b.y/maxs  1+4*b.y/maxs
			make "c.color rgb_  0.4+2*c.y/maxs  0.4+2*c.y/maxs  1+4*c.y/maxs

			if a.y < 0 [make "a.y 0]
			if b.y < 0 [make "b.y 0]
			if c.y < 0 [make "c.y 0]

			make_poly (set a b c) 0
		]
	]
end

make "s maxs/2
make "h maxs*(sqrt 3)/4

make "f 1/2

(trifrac 
	point (-s) 0 (-h)
	point   s  0 (-h)
	point   0  0   h
	maxs/4
)

(make "sky make_poly 
	(set 
		point (-100000) 1000 (-100000)
		point ( 100000) 1000 (-100000)
		point ( 100000) 1000 ( 100000)
		point (-100000) 1000 ( 100000)
	)
	rgb_  0.4  0.4  1
)

fly.always		; free flying until the escape key is pressed

TriCircles (simple) Walker (advanced 3d)