//! this example is for an older version use sketchbook::prelude::*; use sketchbook_env_wgpu::prelude::*; run_sketchbook!(Tree); /* * Original Processing version: https://processing.org/examples/tree.html * * Recursive Tree * by Daniel Shiffman. * * Renders a simple tree-like structure via recursion. * The branching angle is calculated as a function of * the horizontal mouse location. Move the mouse left * and right to change the angle. */ sketch! { content: Tree, env: Wgpu, events: [DrawEvent, MouseEvent], } struct Tree { page: WgpuPage, theta: f32, } impl Setup for Tree { fn setup(page: WgpuPage, _: ()) -> Self { // size(640, 360); Self { page, theta: 0. } } } impl Mouse for Tree {} impl Draw for Tree { fn draw(&mut self) { self.fill(Color::GREEN); self.rect_mode(Mode::Center); self.background(0.); self.frame_rate(30.); // stroke(255); // Let's pick an angle 0 to 90 degrees based on the mouse position let a = (self.mouse_x() / self.width()) * 90.; // Convert it to radians // theta = radians(a); self.theta = a * std::f32::consts::PI / 180.; // Start the tree from the bottom of the screen self.translate((self.width() / 2., self.height() / 2.)); // Draw a line 120 pixels // line(0,0,0,-120); self.rect((0, 300. / 2., 1, 300)); // Move to the end of that line self.translate((0., 0.)); // Start the recursive branching! self.branch(300., 1.); } } impl Tree { fn branch(&mut self, h: f32, c: f32) { // Each branch will be 2/3rds the size of the previous one let h = h * 0.66; let c = c * 0.85; // All recursive functions must have an exit condition!!!! // Here, ours is when the length of the branch is 2 pixels or less if h > 1. { self.push_matrix(); // Save the current state of transformation (i.e. where are we now) self.rotate(self.theta); // Rotate by theta // line(0, 0, 0, -h); // Draw the branch self.fill(Color { red: 1. - c, green: c, blue: 1. - c, alpha: 1., }); self.rect((0, -h / 2., 1, h)); self.translate((0., -h)); // Move to the end of the branch self.branch(h, c); // Ok, now call myself to draw two new branches!! self.pop_matrix(); // Whenever we get back here, we "pop" in order to restore the previous matrix state // Repeat the same thing, only branch off to the "left" this time! self.push_matrix(); self.rotate(-self.theta); // line(0, 0, 0, -h); self.fill(Color { red: 1. - c, green: c, blue: 1. - c, alpha: 1., }); self.rect((0, -h / 2., 1, h)); self.translate((0., -h)); self.branch(h, c); self.pop_matrix(); } } }