Skip to content

Commit f7a5ed2

Browse files
committed
new examples
1 parent 536f1e9 commit f7a5ed2

File tree

2 files changed

+287
-0
lines changed

2 files changed

+287
-0
lines changed

contributed/ball_of_confusion.rb

Lines changed: 232 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,232 @@
1+
# Ball of Confusion Sketch see original by Ben Notiaranni
2+
# http://lazydog-bookfragments.blogspot.com/2008/12/orb-code.html
3+
NUMBER_OF_HAIRS = 10_000
4+
BODY_R = 25.0
5+
MIN_HAIR_LENGTH = 24.0
6+
SHORT_HAIR_LENGTH = 30.0
7+
LONG_HAIR_LENGTH = 10.0
8+
LONG_HAIR_MAX_LENGTH = 30.0
9+
LONG_DENDRITE_LENGTH = 20.0
10+
LONG_DENDRITE_MAX_LENGTH = 60.0
11+
12+
attr_reader :rotation_history, :g_frame, :g_lights, :ball_theta, :ball_phi
13+
attr_reader :camera_r, :camera_theta, :camera_phi, :graphics, :cr
14+
15+
def key_pressed
16+
return unless key == 'l'
17+
@g_lights = !g_lights
18+
end
19+
20+
def settings
21+
size(800, 600, P3D)
22+
smooth
23+
end
24+
25+
def setup
26+
sketch_title 'Ball of Confusion'
27+
colorMode(RGB, 1.0)
28+
background(0.0)
29+
@rotation_history = RotationHistory.new(200)
30+
@g_lights = true
31+
@g_frame = 0
32+
@camera_r = 130.0
33+
@camera_phi = PI / 4
34+
@camera_theta = 0.0
35+
@ball_theta = 0
36+
@ball_phi = 0
37+
@graphics = self.g
38+
# blend_mode(DIFFERENCE)
39+
end
40+
41+
def draw
42+
@camera_r = 180.0 + (sin(g_frame/50.0) + cos(g_frame / 57)) * 25
43+
@g_frame += 1.0
44+
@ball_theta += 2.0 * sin(g_frame/53.0)
45+
@ball_phi += 2.0 * sin(g_frame/83.0)
46+
rotation_history.push(ball_theta, ball_phi)
47+
background(0.0)
48+
camera_spherical(camera_r, camera_phi, -camera_theta)
49+
random_seed(6)
50+
@cr = 0.0
51+
if (g_lights)
52+
@cr = 1.0
53+
lights
54+
x = sin(g_frame / 30.0)
55+
y = sin(g_frame / 37.0)
56+
z = sin(g_frame / 43.0)
57+
directional_light(1.0, 1.0, 1.0, x, y, z)
58+
directional_light(0.3, 0.3, 0.3, -x, -y, -z)
59+
else
60+
@cr = 0.0
61+
no_lights
62+
end
63+
draw_body(BODY_R, cr * 1.0, cr * 0.4, cr * 0.1, 1.0)
64+
begin_shape
65+
draw_spikes(30, BODY_R, LONG_HAIR_LENGTH, LONG_HAIR_MAX_LENGTH)
66+
draw_dendrites(15, BODY_R, LONG_DENDRITE_LENGTH, LONG_DENDRITE_MAX_LENGTH)
67+
draw_fuzz(10_000, MIN_HAIR_LENGTH, SHORT_HAIR_LENGTH)
68+
end_shape
69+
save_frame(data_path'####.png') if frame_count > 100
70+
end
71+
72+
def draw_dendrites(count, br, l1, l2)
73+
count.times do
74+
length = rand(l1..l2)
75+
theta = rand(0.0..360.0)
76+
phi = rand(0.0..180.0)
77+
push_matrix
78+
rotation_history.record(0).draw(graphics)
79+
draw_patch(br + 0.1, theta, phi, 4.radians, 16)
80+
pop_matrix
81+
c1 = color(sin(g_frame / 100.0).abs, sin(g_frame / 123.0).abs, sin(g_frame / 176.0).abs, 1.0)
82+
c2 = color(sin(g_frame / 57.0).abs, sin(g_frame / 23.0).abs, sin(g_frame / 67.0).abs, 0.0)
83+
hair = Hair.new(length*2, br, theta + rand, phi + rand, c1, c2, 1.0)
84+
hair.draw
85+
end
86+
end
87+
88+
def draw_spikes(count, br, l1, l2)
89+
count.times do
90+
theta = rand(0.0..360.0)
91+
phi = rand(0.0..180.0)
92+
push_matrix
93+
rotation_history.record(0).draw(graphics)
94+
draw_patch(br + 0.1, theta, phi, 4.radians, 16)
95+
pop_matrix
96+
length = rand(l1..l2)
97+
(0..10).each do |j|
98+
l = (j == 9) ? length : rand(l1..length)
99+
hair = Hair.new(l, br, theta + rand, phi + rand, color(1.0, 1.0, 1.0, 1.0), color(1.0, 0.4, 0.1, 0.1), 1.0)
100+
hair.draw
101+
end
102+
end
103+
end
104+
105+
def draw_fuzz(count, r1, r2)
106+
push_matrix
107+
rotation_history.record(0).draw(graphics)
108+
begin_shape(LINES)
109+
count.times do
110+
theta = rand(0..TWO_PI)
111+
phi = rand(0..PI)
112+
x1 = cos(theta) * sin(phi)
113+
y1 = sin(theta) * sin(phi)
114+
z1 = cos(phi)
115+
r = rand(r1..r2)
116+
c1 = 1.0
117+
c2 = 1.0 * 0.4
118+
stroke(c1, c1, c1, 0.5)
119+
vertex(x1 * r1, y1 * r1, z1 * r1)
120+
stroke(c2, c2, c2, 0.0)
121+
vertex(x1 * r, y1 * r, z1 * r)
122+
end
123+
end_shape
124+
pop_matrix
125+
end
126+
127+
def draw_body(r, red, green, blue, alpha)
128+
no_stroke
129+
fill(red, green, blue, alpha)
130+
sphere(r)
131+
end
132+
133+
def camera_spherical(r, phi, theta)
134+
x = r * cos(theta) * sin(phi)
135+
y = r * sin(theta) * sin(phi)
136+
z = r * cos(phi)
137+
nx = cos(theta) * cos(phi)
138+
ny = sin(theta) * cos(phi)
139+
nz = -sin(phi)
140+
camera(x, y, z, 0.0, 0.0, 0.0, nx, ny, nz)
141+
end
142+
143+
def draw_patch(r, theta, phi, ar, smoothness)
144+
push_matrix
145+
rotate(theta, 0.0, 0.0, 1.0)
146+
rotate(phi, 0.0, 1.0, 0.0)
147+
begin_shape(TRIANGLE_FAN)
148+
x = r * sin(ar)
149+
z = r * cos(ar)
150+
fill(1.0, 1.0, 1.0, 1.0)
151+
vertex(0.0, 0.0, r)
152+
fill(1.0, 0.0, 0.0, 0.0)
153+
smoothness.times do |i|
154+
vertex(x * cos(TWO_PI * i / smoothness), x * sin(TWO_PI * i / smoothness), z)
155+
end
156+
end_shape
157+
158+
pop_matrix
159+
end
160+
161+
class Hair
162+
attr_reader :length, :r, :theta, :phi, :sections
163+
attr_reader :r1, :g1, :b1, :a1, :r2, :g2, :b2, :a2
164+
165+
def initialize(length, r, theta, phi, c1, c2, smoothness)
166+
@length = length
167+
@r = r
168+
@theta = theta.radians
169+
@phi = phi.radians
170+
@r1 = red(c1)
171+
@g1 = green(c1)
172+
@b1 = blue(c1)
173+
@a1 = alpha(c1)
174+
@r2 = red(c2)
175+
@g2 = green(c2)
176+
@b2 = blue(c2)
177+
@a2 = alpha(c2)
178+
@sections = (length / smoothness).round
179+
end
180+
181+
def draw
182+
push_matrix
183+
begin_shape(LINE_STRIP)
184+
sections.times do |i|
185+
dh = i.to_f / sections
186+
h = r + length * dh
187+
x = h * cos(@theta) * sin(@phi)
188+
y = h * sin(@theta) * sin(@phi)
189+
z = h * cos(@phi)
190+
theta = rotation_history.record(-i).theta.radians
191+
phi = rotation_history.record(-i).phi.radians
192+
x1= x * cos(phi) + z * sin(phi)
193+
y1 = y
194+
z1 = -x * sin(phi) + z * cos(phi)
195+
x = x1 * cos(theta) - y1 * sin(theta)
196+
y = x1 * sin(theta) + y1 * cos(theta)
197+
z = z1
198+
stroke(r1 + (r2 - r1) * dh, g1 + (g2 - g1) * dh, b1 + (b2 - b1) * dh, a1 + (a2 - a1) * dh)
199+
vertex(x, y, z)
200+
end
201+
end_shape
202+
pop_matrix
203+
end
204+
end
205+
206+
# Struct to store rotations, with draw(graphics) method to return rotations
207+
Record = Struct.new(:theta, :phi) do
208+
def draw(gfx)
209+
gfx.rotate_z(theta)
210+
gfx.rotate_y(phi)
211+
end
212+
end
213+
214+
class RotationHistory
215+
attr_reader :history, :size, :frame
216+
217+
def initialize(size = 100)
218+
@history = (0..size).map { Record.new(0, 0) }
219+
@size = size
220+
@frame = 0
221+
end
222+
223+
def push(theta, phi)
224+
@frame += 1
225+
history[frame % size].theta = theta
226+
history[frame % size].phi = phi
227+
end
228+
229+
def record(idx)
230+
history[(frame + idx).abs % size]
231+
end
232+
end
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# Sketch to demonstrate the use of colour tables. A ColourTable object
2+
# consists of a set of ColourRules. Each rule maps a numeric value to
3+
# a colour. The colour to be associated with any value can be found by
4+
# calling the find_colour method of a colour table. If the rules are
5+
# continuous, the returned colour is interpolated between the two
6+
# colour rules closest to the given value. If rules are discrete, only
7+
# exact matches are mapped to a colour.
8+
# Version 1.2, 4th November, 2013.
9+
# Author Jo Wood. Adapted for JRubyArt by Martin Prout 2019
10+
load_library 'gicentreUtils'
11+
java_import 'org.gicentre.utils.colour.ColourTable'
12+
13+
attr_reader :table1, :table2, :table3 # Colour tables to use.
14+
15+
def settings
16+
size(500, 250)
17+
end
18+
19+
def setup
20+
sketch_title('GiCentre ColourTable Example in JRubyArt')
21+
# Create a continuous Brewer colour table (YlOrBr6).
22+
@table1 = ColourTable.new
23+
table1.add_continuous_colour_rule(0.5 / 6, 255, 255, 212)
24+
table1.add_continuous_colour_rule(1.5 / 6, 254, 227, 145)
25+
table1.add_continuous_colour_rule(2.5 / 6, 254, 196, 79)
26+
table1.add_continuous_colour_rule(3.5 / 6, 254, 153, 41)
27+
table1.add_continuous_colour_rule(4.5 / 6, 217, 95, 14)
28+
table1.add_continuous_colour_rule(5.5 / 6, 153, 52, 4)
29+
# Create a preset colour table and save it as a file
30+
@table2 = ColourTable.get_preset_colour_table(ColourTable::IMHOF_L3, 0, 1)
31+
ColourTable.write_file(table2, create_output(data_path('imhofLand3.ctb')))
32+
# Read in a colour table from a ctb file.
33+
@table3 = ColourTable.read_file(create_input(data_path('imhofLand3.ctb')))
34+
end
35+
36+
def draw
37+
background(255)
38+
# Draw the continuous Brewer colour table.
39+
draw_color_table(table1, 0.001, 10)
40+
# Draw the discrete version of the Brewer colour table.
41+
draw_color_table(table1, 1 / 6.0, 70, true)
42+
# Draw the preset colour table.
43+
draw_color_table(table2, 0.001, 130)
44+
# Draw the colour table loaded from a file.
45+
draw_color_table(table3, 1 / 6.0, 190)
46+
end
47+
48+
def draw_color_table(table, increment, height, outline = false)
49+
(0..1.0).step(increment) do |i|
50+
fill(table.find_colour(i))
51+
outline ? stroke(0, 150) : stroke(table.find_colour(i))
52+
rect(width * i, height, width * increment, 50) unless outline
53+
rect(width * i, height, width * increment, 50, 2) if outline
54+
end
55+
end

0 commit comments

Comments
 (0)