Skip to content

Commit a2daa1e

Browse files
committed
re-arrange grid method
1 parent 91e26d1 commit a2daa1e

File tree

7 files changed

+291
-0
lines changed

7 files changed

+291
-0
lines changed
File renamed without changes.
365 KB
Loading

examples/grid_method/data/mask.png

10.4 KB
Loading
File renamed without changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
#!/usr/bin/env jruby
2+
require 'propane'
3+
# Example of using noise to rotate a grid of arrows
4+
#
5+
class GenerativeArrowRotate < Propane::App
6+
7+
load_library :pdf
8+
attr_reader :version, :time_seed, :save_one_frame, :arrow
9+
STEP = 40
10+
POINTS = [
11+
[0, -55], [6, 0], [16, 10], [2, 10], [0, -10], [-2, 10], [-16, 10], [-6, 0]
12+
].freeze
13+
14+
def setup
15+
sketch_title 'Generative Arrow'
16+
# resolution does not really matter since we are working with vectors
17+
frame_rate(35)
18+
@version = 0 # if we grab multiple frames, they will be numbered
19+
@time_seed = 0.1 # seed for the third dimension of the noise
20+
@save_one_frame = false
21+
create_arrow
22+
end
23+
24+
def draw
25+
# turn on recording for this frame if we clicked the mouse
26+
begin_record(PDF, data_path("Line_#{version}.pdf")) if (save_one_frame == true)
27+
background(255)
28+
@time_seed = millis / 5000.0 # change noise over time
29+
grid(width, height, STEP, STEP) do |cx, cy| # iterate down and accross the page
30+
push_matrix
31+
translate(cx + STEP / 2, cy + STEP / 2) # set the position of each arrow
32+
# rotate using noise
33+
rotate(4.0 * PI * noise(cx / 400.0, cy / 400.0, time_seed))
34+
# scale(1)
35+
shape(arrow) # draw our arrow
36+
pop_matrix
37+
end
38+
if (save_one_frame == true)
39+
end_record
40+
@save_one_frame = false
41+
@version += 1
42+
end
43+
end
44+
45+
def mouse_pressed
46+
@save_one_frame = true
47+
end
48+
49+
def create_arrow # custom shape for our arrow
50+
@arrow = create_shape
51+
arrow.begin_shape
52+
arrow.fill(200, 0, 0)
53+
arrow.no_stroke
54+
arrow.stroke_weight(2)
55+
POINTS.each { |pt| arrow.vertex(*pt) }
56+
arrow.end_shape(CLOSE)
57+
end
58+
59+
def settings
60+
size(1000, 1000)
61+
end
62+
end
63+
64+
GenerativeArrowRotate.new

examples/grid_method/hex_variation.rb

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
#!/usr/bin/env jruby
2+
require 'propane'
3+
# Part of the ReCode Project (http://recodeproject.com)
4+
# Based on "Hex Variation" by William Kolmyjec
5+
# Originally published in "Computer Graphics and Art" vol3 no4, 1978
6+
# Copyright (c) 2012 Steve Berrick - OSI/MIT license (http://recodeproject/license).
7+
class HexVariation < Propane::App
8+
9+
SIZE = 20 # hexagon radius
10+
ANGLES = [0, THIRD_PI, THIRD_PI * 2].freeze
11+
12+
def setup
13+
sketch_title 'Hex Variation'
14+
no_loop
15+
no_fill
16+
stroke(0)
17+
stroke_weight(2)
18+
end
19+
20+
def draw
21+
# clear background
22+
background(255)
23+
# line length (hypotenuse)
24+
h = sin(THIRD_PI) * SIZE
25+
jsize = height / h
26+
isize = width / (3 * SIZE)
27+
grid(isize, 2 + jsize.to_i) do |i, j|
28+
# reference points (centre of each hexagon)
29+
x = i * SIZE * 3 + (SIZE / 2)
30+
y = j * h
31+
# offset each odd row
32+
x += SIZE * 1.5 unless (j % 2).zero?
33+
push_matrix
34+
translate(x, y)
35+
# random hexagon rotation (0, 120, 240 degrees)
36+
rotate(ANGLES.sample)
37+
# draw line
38+
line(0, -h, 0, h)
39+
# draw arcs
40+
arc(-SIZE, 0, SIZE, SIZE, -THIRD_PI, THIRD_PI)
41+
arc( SIZE, 0, SIZE, SIZE, THIRD_PI * 2, THIRD_PI * 4)
42+
pop_matrix
43+
end
44+
end
45+
46+
def mouse_pressed
47+
redraw
48+
end
49+
50+
def settings
51+
size 600, 900
52+
end
53+
end
54+
55+
HexVariation.new

examples/grid_method/luciernagas.rb

+172
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
#!/usr/bin/env jruby
2+
require 'propane'
3+
# Luciernagas
4+
# After an original by Marcel Miranda aka reaktivo
5+
# https://github.com/reaktivo/rp-luciernagas
6+
# translated and updated by Martin Prout for JRubyArt
7+
# features use of Vec2D class and grid method
8+
class Luciernagas < Propane::App
9+
10+
load_library :control_panel
11+
12+
attr_reader :panel, :hide, :image_mask, :spots
13+
ACCURACY = 4
14+
15+
# Firefly holder
16+
Flyer = Struct.new(:pos, :to_pos, :rotation, :positions)
17+
18+
def settings
19+
size 1024, 480, P2D
20+
smooth
21+
end
22+
23+
def setup
24+
sketch_title 'Luciernagas'
25+
control_panel do |control|
26+
control.title 'Firefly Controller'
27+
control.look_feel 'Nimbus'
28+
control.slider(:speed, 0..20, 5)
29+
control.slider(:tail_length, 0..400, 30)
30+
control.slider(:rotation_max, 0..30, 7)
31+
control.slider(:target_radius, 5...100, 20)
32+
control.slider(:spot_distance, 5..200, 80)
33+
control.button :reset
34+
@panel = control
35+
end
36+
@hide = false
37+
@spotlight = create_spotlight
38+
@background = load_image(data_path('background.png'))
39+
@image_mask = load_image(data_path('mask.png'))
40+
load_spots(image_mask, ACCURACY)
41+
reset
42+
end
43+
44+
def reset
45+
@flyers = (0..100).map { create_flyer }
46+
end
47+
48+
def draw
49+
unless hide
50+
@hide = true
51+
panel.set_visible(hide)
52+
end
53+
image @background, 0, 0
54+
draw_lights
55+
draw_flyers
56+
end
57+
58+
def draw_lights
59+
lights = create_graphics width, height, P2D
60+
lights.begin_draw
61+
@flyers.each do |flyer|
62+
lights.push_matrix
63+
position = flyer.pos
64+
lights.translate position.x, position.y
65+
lights.image @spotlight, -@spotlight.width / 2, -@spotlight.height / 2
66+
lights.pop_matrix
67+
end
68+
lights.end_draw
69+
image_mask.mask lights
70+
image image_mask, 0, 0
71+
end
72+
73+
def draw_flyers
74+
rotation_max = @rotation_max / 100 * TWO_PI
75+
@flyers.each do |flyer|
76+
# check if point reached
77+
if flyer.pos.dist(flyer.to_pos) < @target_radius
78+
spot = find_spot_near flyer.pos, @spot_distance
79+
flyer.to_pos = spot
80+
end
81+
# set new rotation
82+
to_rotation = (flyer.to_pos - flyer.pos).heading
83+
to_rotation = find_nearest_rotation(flyer.rotation, to_rotation)
84+
# rotate to new direction
85+
if flyer.rotation < to_rotation
86+
flyer.rotation = flyer.rotation + rotation_max
87+
flyer.rotation = to_rotation if flyer.rotation > to_rotation
88+
else
89+
flyer.rotation = flyer.rotation - rotation_max
90+
flyer.rotation = to_rotation if flyer.rotation < to_rotation
91+
end
92+
# add tail position
93+
flyer.positions << flyer.pos.dup
94+
flyer.positions.shift while flyer.positions.size > @tail_length
95+
# set flyer position
96+
flyer.pos.x = flyer.pos.x + @speed * cos(flyer.rotation)
97+
flyer.pos.y = flyer.pos.y + @speed * sin(flyer.rotation)
98+
# draw flyer tail
99+
draw_tail flyer
100+
# draw flyer
101+
no_stroke
102+
fill 201, 242, 2
103+
push_matrix
104+
translate flyer.pos.x, flyer.pos.y
105+
ellipse 0, 0, 5, 5
106+
pop_matrix
107+
end
108+
end
109+
110+
def create_flyer
111+
spot = rand_spot
112+
to_spot = find_spot_near spot, @spot_distance
113+
rotation = rand * TWO_PI
114+
Flyer.new(spot, to_spot, rotation, [])
115+
end
116+
117+
def draw_tail(flyer)
118+
positions = flyer.positions
119+
return unless positions && !positions.empty?
120+
alpha_add = (255 / positions.size).to_i
121+
positions.each_index do |i|
122+
stroke(255, i * alpha_add)
123+
if i < positions.size - 2
124+
line(positions[i].x, positions[i].y, positions[i + 1].x, positions[i + 1].y)
125+
end
126+
end
127+
end
128+
129+
def load_spots(spot_image, accuracy = ACCURACY)
130+
@spots = []
131+
spot_image.load_pixels
132+
corner_color = spot_image.get 0, 0
133+
grid(spot_image.width, spot_image.height, accuracy, accuracy) do |x, y|
134+
color = spot_image.get(x, y)
135+
spots << Vec2D.new(x, y) if color != corner_color
136+
end
137+
end
138+
139+
def rand_spot
140+
spots.sample
141+
end
142+
143+
def find_spot_near(pos, distance)
144+
spot = Vec2D.new(Float::INFINITY, Float::INFINITY)
145+
spot = rand_spot until spot.dist(pos) < distance
146+
spot
147+
end
148+
149+
def find_nearest_rotation(from, to)
150+
dif = (to - from) % TWO_PI
151+
if dif != dif % PI
152+
dif = dif < 0 ? dif + TWO_PI : dif - TWO_PI
153+
end
154+
from + dif
155+
end
156+
157+
def create_spotlight
158+
size = 60
159+
spotlight = create_graphics size, size, P2D
160+
spotlight.begin_draw
161+
spotlight.no_stroke
162+
spotlight.fill 255, 60
163+
# spotlight.fill 255, 40
164+
half_size = size / 2
165+
spotlight.ellipse half_size, half_size, half_size, half_size
166+
spotlight.filter BLUR, 4
167+
spotlight.end_draw
168+
spotlight
169+
end
170+
end
171+
172+
Luciernagas.new

0 commit comments

Comments
 (0)