Fractal Tree
Bhathiya Perera
Hint: Refresh to get a new random tree
import raylib as rl
import raylib.utils
import libs.numbers as num
import libs.perlin
import libs.random
class State:
width: float
height: float
angle: float
frame_count: u64
blue: rl.Color
green: rl.Color
color3: rl.Color
def branch(x: float, y: float, length: float, angle: float, s: State) -> None:
if length < 4.0f:
leaf_width = random.random_betweenf(1.0f, 3.0f)
leaf_height = random.random_betweenf(3.0f, 6.0f)
lerped_green = utils.lerp_color(s.green, s.blue, utils.remap(x, 0.0f, s.width, 0.0f, 1.0f) * 2.0f)
color = utils.lerp_color(lerped_green, s.color3, utils.remap(y, 0.0f, s.height, 0.0f, 1.0f) * 1.5f)
rl.draw_ellipse(num.f2i(x), num.f2i(y), leaf_height, leaf_width, color)
return
wind = utils.sin_deg(perlin.noise1df(num.uu2f(s.frame_count) / 50.0f)) * 100.0f * utils.sin_deg(num.uu2f(s.frame_count) / 2.0f)
next_y = y - length * utils.cos_deg(angle)
next_x = x + length * utils.sin_deg(angle)
thick = utils.remap(length, 0.0f, s.height / 4.0f, 2.0f, 6.0f)
rl.draw_line_ex(rl.vector2(x, y), rl.vector2(next_x, next_y), thick, rl.color(152, 50, 1, 255))
r1 = random.random_betweenf(0.3f, 0.9f)
r2 = random.random_betweenf(0.5f, 0.8f)
branch(next_x, next_y, (length * r2), angle + s.angle + wind * 10.0f, s)
branch(next_x, next_y, (length * r1), angle - s.angle + wind * 10.0f, s)
def update_draw_frame(s: State) -> None:
rl.clear_background(rl.color(255, 255, 255, 255))
branch(s.width / 2.0f, s.height, s.height / 4.0f, 0.0f, s)
def main() -> int:
s: State = State()
s.angle = random.random_betweenf(30.0f, 45.0f)
s.width = 600.0f
s.height = 600.0f
s.frame_count = 0u64
s.blue = rl.color(0, 255, 214, 255)
s.green = rl.color(0, 255, 0, 255)
s.color3 = rl.color(255, 45, 156, 255)
rl.init_window(num.f2i(s.width), num.f2i(s.height), "Fractal Tree in the Wind")
rl.set_target_fps(120)
seed: u64 = random.init_random()
while not rl.window_should_close():
rl.begin_drawing()
update_draw_frame(s)
rl.draw_fps(0, 0)
rl.end_drawing()
s.frame_count += 1u64
random.set_seed(seed)
rl.close_window()
del s
return 0