/
retained_menger.rb
126 lines (105 loc) · 2.99 KB
/
retained_menger.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
#!/usr/bin/env jruby -v -W2
# frozen_string_literal: true
require 'propane'
require 'arcball'
##########################
# RetainedMenger.rb
# (processing-3.0)
# author Martin Prout
##########################
class RetainedMenger < Propane::App
PTS = [-1, 0, 1]
MIN_SIZE = 20
attr_reader :menger
def setup
sketch_title 'Retained Menger'
Processing::ArcBall.init(self)
@menger = create_shape(GROUP)
create_menger(0, 0, 0, height * 0.8)
end
def draw
background(20, 20, 200)
no_stroke
lights
define_lights
render
end
def render
menger.set_fill(color(224, 223, 219))
menger.set_ambient(50)
menger.set_specular(150)
shape(menger)
end
def create_menger(xx, yy, zz, sz)
u = sz / 3.0
if sz < MIN_SIZE # recursion limited by minimum cube size
no_stroke
menger.add_child(create_cube(xx, yy, zz, sz)) # create and add a cube
else
PTS.each do |i|
PTS.each do |j|
PTS.each do |k|
if (i.abs + j.abs + k.abs) > 1
create_menger(xx + (i * u), yy + (j * u), zz + (k * u), u)
end
end
end
end
end
end
def create_cube(xx, yy, zz, sz)
dim = sz / 2.0
cube = create_shape
cube.begin_shape(QUADS)
# Front face
cube.fill(255)
cube.normal(0, 0, 1)
cube.vertex(-dim + xx, -dim + yy, -dim + zz)
cube.vertex(+dim + xx, -dim + yy, -dim + zz)
cube.vertex(+dim + xx, +dim + yy, -dim + zz)
cube.vertex(-dim + xx, +dim + yy, -dim + zz)
# Back face
cube.normal(0, 0, -1)
cube.vertex(-dim + xx, -dim + yy, +dim + zz)
cube.vertex(+dim + xx, -dim + yy, +dim + zz)
cube.vertex(+dim + xx, +dim + yy, +dim + zz)
cube.vertex(-dim + xx, +dim + yy, +dim + zz)
# Left face
cube.normal(1, 0, 0)
cube.vertex(-dim + xx, -dim + yy, -dim + zz)
cube.vertex(-dim + xx, -dim + yy, +dim + zz)
cube.vertex(-dim + xx, +dim + yy, +dim + zz)
cube.vertex(-dim + xx, +dim + yy, -dim + zz)
# Right face
cube.normal(-1, 0, 0)
cube.vertex(+dim + xx, -dim + yy, -dim + zz)
cube.vertex(+dim + xx, -dim + yy, +dim + zz)
cube.vertex(+dim + xx, +dim + yy, +dim + zz)
cube.vertex(+dim + xx, +dim + yy, -dim + zz)
# Top face
cube.normal(0, 1, 0)
cube.vertex(-dim + xx, -dim + yy, -dim + zz)
cube.vertex(+dim + xx, -dim + yy, -dim + zz)
cube.vertex(+dim + xx, -dim + yy, +dim + zz)
cube.vertex(-dim + xx, -dim + yy, +dim + zz)
# Bottom face
cube.normal(0, -1, 0)
cube.vertex(-dim + xx, +dim + yy, -dim + zz)
cube.vertex(+dim + xx, +dim + yy, -dim + zz)
cube.vertex(+dim + xx, +dim + yy, +dim + zz)
cube.vertex(-dim + xx, +dim + yy, +dim + zz)
cube.end_shape
cube
end
def define_lights
ambient_light(180, 180, 180)
point_light(30, 30, 30, 200, 240, 0)
directional_light(50, 50, 50, 1, 0, 0)
spot_light(30, 30, 30, 0, 40, 200, 0, -0.5, -0.5, PI / 2, 2)
end
def settings
size(640, 480, P3D)
smooth(8)
end
end
RetainedMenger.new