-
Notifications
You must be signed in to change notification settings - Fork 2
/
basic_recursion_tree.rb
147 lines (106 loc) · 3.72 KB
/
basic_recursion_tree.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# This is a basic example of recursion trees or fractle tree
# Simpley this will split the branch at a given angle at the end of each branch
require 'rubygems'
require 'gosu'
module Common
module Screen
MODE = false # THIS SETS FULLSCREEN OR NOT
WIDTH = 800
HEIGHT = 600
end
end
class Numeric
def gosu_to_radians
(self - 90) * Math::PI / 180.0
end
def radians_to_gosu
self * 180.0 / Math::PI + 90
end
end
include Common
class Tree
def initialize(world, colour, bot_margin, x_coords, layer)
@world = world
@colour = colour
@bot_margin = bot_margin
@x = x_coords
@layer = layer
new_tree
end
def new_tree
angle_list = (20..90).to_a
shrink_list = (2..6).to_a
split_list = (5..12).to_a
initial_branch_length = (75..300).to_a
@max_splits = split_list[rand(split_list.length)] # how many times the branches have split
@angle = (Math::PI / 4) # the angle of the splits
@shrink = "0.#{shrink_list[rand(shrink_list.length)]}".to_f
@degree_shirink = angle_list[rand(angle_list.length)]
@branches = []
@branches << [ [[@x, Screen::HEIGHT - @bot_margin], [@x, Screen::HEIGHT - initial_branch_length[rand(initial_branch_length.length)]]] ] # First Branch
end
def update
last_section = @branches.last
new_section = []
if @branches.length < @max_splits
last_section.each do |b|
old_x1, old_y1 = b[0][0], b[0][1]
old_x2, old_y2 = b[1][0], b[1][1]
old_length = Gosu::distance(old_x1, old_y1, old_x2, old_y2)
new_x, new_y = old_x2, old_y2
new_length = (old_length * @shrink).to_i
angle = (Gosu::angle(old_x1, old_y1, old_x2, old_y2)).to_i
first_branch_angle = angle + @degree_shirink
second_branch_angle = angle - @degree_shirink
first_branch_x = new_x + Gosu::offset_x(first_branch_angle, new_length)
first_branch_y = new_y + Gosu::offset_y(first_branch_angle, new_length)
second_branch_x = new_x + Gosu::offset_x(second_branch_angle, new_length)
second_branch_y = new_y + Gosu::offset_y(second_branch_angle, new_length)
new_section << [[new_x, new_y], [first_branch_x.to_i, first_branch_y.to_i]]
new_section << [[new_x, new_y], [second_branch_x.to_i, second_branch_y.to_i]]
end
@branches << new_section
end
end
def draw
@branches.each do |tree_section|
tree_section.each do |b|
@world.draw_line(b[0][0], b[0][1], @colour, b[1][0], b[1][1], @colour, @layer)
end
end
end
end
class Game < Gosu::Window
def initialize
super(Screen::WIDTH, Screen::HEIGHT, Screen::MODE)
@tree = Tree.new(self, 0xFF000000, 10, Screen::WIDTH / 2, 2)
self.caption = "Basic Recursion Tree"
# Gosu Logo
@gosulogo = Gosu::Image.new(self, "media/gosu_logo.png", false)
@text = Gosu::Font.new(self, 'media/bitlow.ttf', 10)
@colors = {:white => 0xFFFFFFFF, :gray => 0xFF333333}
end
def update
@tree.update
end
def draw
@tree.draw
self.draw_quad(0, 0, @colors[:white],
Screen::WIDTH, 0, @colors[:white],
0, Screen::HEIGHT, @colors[:gray],
Screen::WIDTH, Screen::HEIGHT, @colors[:gray],
0)
# Drawing the Logos
@gosulogo.draw(10, Screen::HEIGHT - 43, 1)
@text.draw("PRESS SPACE TO GENERATE A NEW TREE", 10, 10, 1, 1.5, 1.5, 0xFF000000)
end
def button_down(id)
if button_down? Gosu::KbEscape
close
end
if button_down? Gosu::KbSpace
@tree.new_tree
end
end
end
Game.new.show