# Create A Tree Generator (in less than 100 lines of V)

# A Magical Tree Generator

In this post, I'll show you how to do what you've always wanted. Namely a magical tree generator - and of course, learn V in the making of this.

This will all be done in exactly 90 lines of code.

## V

First of all, what is V? This is easy, I'll just simply refer you to my other post: https://madco.me/code-in-v

## Tree Generator

Let's get started!

As V is much like Go in it's code, we need a module and some imports

```v
module main

import gg
import gx
import math
import rand
import sokol.sapp
```

These are just a few things V provides for us to use, and that we'll need.

* `gg` is our drawing tool, think of it as the plain ol' plaint buddy from MS.
* `gx` is the a plalette of colours for us to use.
* `math` is for `PI`.
* `rand` to gain some randomness. We do not want the same thing multiple times.
* `sokol.sapp`, to be honest, I have yet to figure this.

```v
const (
	win_width  = 600
	win_height = 600
)
```

This will be the size of our canvas.

```v
struct App {
mut:
	gg    &gg.Context
}
```

This `struct` will be in charge of drawing.

```v
struct Branch {
mut:
	x f32
	y f32
	cx f32
	cy f32
	rad f32
	len f32
}
```

This struct, however, just simply a branch of our tree.

```v
fn main() {
	mut app := &App{
		gg: 0
	}

	app.gg = gg.new_context({
		bg_color: gx.rgba(255, 155, 155, 0)
		width: win_width
		height: win_height
		use_ortho: true
		create_window: true
		window_title: 'Tree Vv'
		keydown_fn: frame
		user_data: app
	})

	app.gg.run()
}
```

This is more fun, but to keep this simple, just know that this will create our paint brush.

```v
fn frame(c sapp.KeyCode, m sapp.Modifier, app &App) {
	b1 := &Branch{
		x: f32(win_width / 2)
		y: f32(win_height)
		cx: f32(win_width / 2)
		cy: f32(win_height)
		rad: f32(math.pi / 2)
		len: rand.f32n(100)
	}

	app.gg.begin()
	app.draw_branch(b1, 1)
	app.draw_branch(b1, -1)
	app.gg.end()
}
```

The `frame` is where the fun happens! It's in charge of generating a new tree for every key-press.

We start with a simple branch, on `X` & `Y` positions, along with the old postions `CX` & `CY`.

We also generate the start radians, and a random length of the branch.

```v
fn (app &App) draw_branch(b &Branch, mul f32) {
	cos := f32(math.cos(b.rad))
	sin := f32(math.sin(b.rad))

	x_tmp := b.cx - cos * b.len
	y_tmp := b.cy - sin * b.len

	app.gg.draw_line(b.cx, b.cy, x_tmp, y_tmp, gx.black)

	rad := rand.f32n(math.pi / 4)

	b1 := &Branch{
		x: b.cx
		y: b.cy
		cx: x_tmp
		cy: y_tmp
		rad: b.rad + rad * mul
		len: b.len - rand.f32n(25)
	}

	if b1.len > 10 {
		app.draw_branch(b1, 1)
		app.draw_branch(b1, -1)
	} else {
		app.gg.draw_circle(b1.cx, b1.cy, 4, gx.white)
	}
}
```

Here we simply calulate the branch's new `X` & `Y` positions. Re-use our old to as the new `CX` & `CY`.

We then draw a new line. Randomizes a number between `0` and `PI / 4`, and generaets a new rbanch from those values.

If the length of our branch is then above `10`, we does the exact same thing again, becasue insanity, right?

If the branch's length is below or equals to `10` we draw a leaf.

Easy, right? The complete code is below my plug.

## Shameless Plug

Before you turn to the complete code, please take a look at this beauty! [![placetree.art](https://placetree.art/tree?w=750&h=800&random=1)](https://placetree.art)

> I'd recommend you to click on the image to gain access to a tree placeholder!

## Our Generator

The generator we've just created will of not be as beautiful as the above out-put, but it's a start nonetheless.

![Screenshot from 2020-12-30 02-37-39.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1609292334156/mf6wd0JDG.png)

## Complete Code

```v
module main

import gg
import gx
import math
import rand
import sokol.sapp

const (
	win_width  = 600
	win_height = 600
)

struct App {
mut:
	gg    &gg.Context
}

struct Branch {
mut:
	x f32
	y f32
	cx f32
	cy f32
	rad f32
	len f32
}

fn main() {
	mut app := &App{
		gg: 0
	}

	app.gg = gg.new_context({
		bg_color: gx.rgba(255, 155, 155, 0)
		width: win_width
		height: win_height
		use_ortho: true
		create_window: true
		window_title: 'Tree Vv'
		keydown_fn: frame
		user_data: app
	})

	app.gg.run()
}

fn frame(c sapp.KeyCode, m sapp.Modifier, app &App) {
	b1 := &Branch{
		x: f32(win_width / 2)
		y: f32(win_height)
		cx: f32(win_width / 2)
		cy: f32(win_height)
		rad: f32(math.pi / 2)
		len: rand.f32n(100)
	}

	app.gg.begin()
	app.draw_branch(b1, 1)
	app.draw_branch(b1, -1)
	app.gg.end()
}

fn (app &App) draw_branch(b &Branch, mul f32) {
	cos := f32(math.cos(b.rad))
	sin := f32(math.sin(b.rad))

	x_tmp := b.cx - cos * b.len
	y_tmp := b.cy - sin * b.len

	app.gg.draw_line(b.cx, b.cy, x_tmp, y_tmp, gx.black)

	rad := rand.f32n(math.pi / 4)

	b1 := &Branch{
		x: b.cx
		y: b.cy
		cx: x_tmp
		cy: y_tmp
		rad: b.rad + rad * mul
		len: b.len - rand.f32n(25)
	}

	if b1.len > 10 {
		app.draw_branch(b1, 1)
		app.draw_branch(b1, -1)
	} else {
		app.gg.draw_circle(b1.cx, b1.cy, 4, gx.white)
	}
}
```

---

{ Best, [Mads Bram Cordes](https://buymeacoff.ee/mc) }
