Skip to content

Instantly share code, notes, and snippets.

@el3
Created April 7, 2023 18:53
Show Gist options
  • Save el3/7d6ce674d30da374dcc50e26e3acf0eb to your computer and use it in GitHub Desktop.
Save el3/7d6ce674d30da374dcc50e26e3acf0eb to your computer and use it in GitHub Desktop.
from kivy.app import App
from kivy.clock import Clock
from kivy.uix.floatlayout import FloatLayout
from kivy.graphics import Line, Color
from kivy.vector import Vector
from kivy.core.window import Window
from functools import partial
from random import randint
import threading
class Branch(Line):
span = 0
origin = [0,0]
def __init__(self, sp, angle, plane, length, growfactor, generation=1, **kwargs):
self.growfactor = growfactor
self.generation = generation
self.angle = angle
self.sp = Vector(sp)
self.sv = self.sp
self.plane = plane
self.points = [*sp,*sp]
self.max_span = length*growfactor
threading.Thread(target=self.grow,daemon=True).start()
super().__init__(**kwargs)
def grow(self,dt=0):
points = self.points
sv = Vector(points[-2:]) - self.sp
sv = sv.rotate(-self.angle)
sv = sv + [0,2]
sv = sv.rotate(self.angle)
sv = sv + self.sp
points[-2:] = sv
Clock.schedule_once(partial(self.set_points,points))
self.span += 2
return True
def set_points(self, points, dt):
self.points = list(points)
if self.span < (self.max_span):
threading.Thread(target=self.grow,daemon=True).start()
else:
if self.generation < self.plane.generations:
self.plane.growing -= 1
Clock.schedule_once(self.node)
def node(self,dt=0):
if self.plane.growing < self.plane.max_growing:
if randint(0,100) > 50:
self.plane.growing += 1
Clock.schedule_once(self.add_b1)
if randint(0,100) > 50:
self.plane.growing += 1
Clock.schedule_once(self.add_b2)
else:
self.plane.growing += 1
Clock.schedule_once(self.add_b2)
if randint(0,100) > 50:
self.plane.growing += 1
Clock.schedule_once(self.add_b1)
else:
Clock.schedule_once(self.node)
def add_b(self,angle):
ev = Vector(*self.points[-2:])
if self.generation > 8:
c = Color(0,8/self.generation,0,.8)
else:
c = Color(0.45, 0.2, 0, 5/self.generation)
b = Branch(ev, angle, self.plane, self.max_span, self.growfactor, self.generation + 1, width=(self.width - 1 or 1))
self.plane.canvas.add(c)
self.plane.canvas.add(b)
self.plane.canvas.add(Color(0.45,0.2,0))
def add_b1(self,dt):
angle = self.angle - randint(25,35)
self.add_b(angle)
def add_b2(self, dt):
angle = self.angle + randint(25,35)
self.add_b(angle)
class Plane(FloatLayout):
generations = 20
growing = 0
max_growing = 200
def __init__(self,**kwargs):
super().__init__(**kwargs)
Clock.schedule_once(self.init)
Clock.schedule_interval(self.init,10)
def init(self,dt):
self.start1 = 650, 200
self.growing = 0
self.canvas.clear()
self.canvas.after.clear()
self.canvas.add(Color(0.45,0.2,0))
self.tree = Branch(self.start1,0,self,50,0.9,width=10)
self.canvas.add(self.tree)
self.roots = Branch(self.start1,180,self,20,1,11,width=8)
self.canvas.add(self.roots)
class TestApp(App):
def build(self):
Window.maximize()
return Plane()
TestApp().run()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment