-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathtower.rb
More file actions
86 lines (74 loc) · 2.52 KB
/
tower.rb
File metadata and controls
86 lines (74 loc) · 2.52 KB
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
# Original by Ira Greenberg
# 3D castle tower constructed out of individual bricks.
# Uses the PVecor and Cube classes.
def setup
@bricks_per_layer = 16
@brick_layers = 18
@brick_width, @brick_height, @brick_depth = 60, 25, 25
@radius = 175.0
@angle = 0
size 640, 360, P3D
@brick = Cubeish.new(@brick_width, @brick_height, @brick_depth)
end
def draw
background 225
@temp_x, @temp_y, @temp_z = 0, 0, 0
fill 182, 62, 29
no_stroke
lights
translate(width/2.0, height*1.2, -380) # move viewpoint into position
rotate_x(radians(-45)) # tip tower to see inside
rotate_y(frame_count * PI/600) # slowly rotate tower
@brick_layers.times {|i| draw_layer(i) }
end
def draw_layer(layer_num)
@layer_num = layer_num
@temp_y -= @brick_height # increment rows
@angle = 360.0 / @bricks_per_layer * @layer_num / 2.0 # alternate brick seams
@bricks_per_layer.times {|i| draw_bricks(i) }
end
def draw_bricks(brick_num)
@brick_num = brick_num
@temp_z = cos(radians(@angle)) * @radius
@temp_x = sin(radians(@angle)) * @radius
push_matrix
translate @temp_x, @temp_y, @temp_z
rotate_y(radians(@angle))
top_layer = @layer_num == @brick_layers - 1
even_brick = @brick_num % 2 == 0
@brick.create unless top_layer # main tower
@brick.create if top_layer && even_brick # add crenelation
pop_matrix
@angle += 360.0 / @bricks_per_layer
end
# The Cubeish class works a little different than the cube in the
# Processing example. SIDES tells you where the negative numbers go.
# We dynamically create each of the PVectors by passing in the
# appropriate signs.
class Cubeish
SIDES = {:front => ['-- ', ' - ', ' ', '- '],
:left => ['-- ', '---', '- -', '- '],
:right => [' - ', ' --', ' -', ' '],
:back => ['---', ' --', ' -', '- -'],
:top => ['-- ', '---', ' --', ' - '],
:bottom => ['- ', '- -', ' -', ' ']}
SIGNS = {'-' => -1,
' ' => 1}
def initialize(width, height, depth)
@vertices = {}
@w, @h, @d = width, height, depth
SIDES.each do |side, signs|
@vertices[side] = signs.map do |s|
s = s.split('').map {|el| SIGNS[el] }
App::PVector.new(s[0]*@w/2, s[1]*@h/2, s[2]*@d/2)
end
end
end
def create
@vertices.each do |name, vectors|
begin_shape App::QUADS
vectors.each {|v| vertex(v.x, v.y, v.z) }
end_shape
end
end
end