picrate 0.0.2-java → 0.0.3-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +5 -4
- data/Rakefile +1 -1
- data/docs/_classes/aabb/aabb.md +28 -0
- data/docs/_classes/app/app.md +38 -0
- data/docs/_classes/app_render/app_render.md +93 -0
- data/docs/_classes/arc_ball/arc_ball.md +33 -0
- data/docs/_classes/chooser/chooser.md +56 -0
- data/docs/_classes/deglut/deglut.md +20 -0
- data/docs/_classes/library_proxy/library_proxy.md +76 -0
- data/docs/_classes/vec2d/vec2d.md +53 -0
- data/docs/_classes/vec3d/vec3d.md +53 -0
- data/docs/_config.yml +36 -7
- data/docs/_editors/vim.md +63 -0
- data/docs/_gems/gems/gems.md +29 -0
- data/docs/_gems/other_gems/other_gems.md +198 -0
- data/docs/_layouts/post.html +6 -6
- data/docs/_libraries/control_panel.md +137 -0
- data/docs/_libraries/custom.md +126 -0
- data/docs/_libraries/custom_java.md +162 -0
- data/docs/_libraries/gems.md +57 -0
- data/docs/_libraries/library_proxy.md +9 -0
- data/docs/_libraries/picrate.md +511 -0
- data/docs/_libraries/processing.md +126 -0
- data/docs/_libraries/vector_utils.md +126 -0
- data/docs/_magic/java.md +30 -0
- data/docs/_magic/jruby.md +105 -0
- data/docs/_magic/processing.md +297 -0
- data/docs/_magic/ruby.md +31 -0
- data/docs/_methods/alternative_methods.md +66 -0
- data/docs/_methods/color.md +109 -0
- data/docs/_methods/data_path.md +109 -0
- data/docs/_methods/draw.md +20 -0
- data/docs/_methods/key_pressed.md +27 -0
- data/docs/_methods/library_loader.md +49 -0
- data/docs/_methods/map1d.md +77 -0
- data/docs/_methods/methods_summary.md +103 -0
- data/docs/_methods/mouse_pressed.md +25 -0
- data/docs/_methods/post_initialize.md +9 -0
- data/docs/_methods/processing_api.md +46 -0
- data/docs/_methods/settings.md +48 -0
- data/docs/_methods/setup.md +36 -0
- data/docs/_methods/sketch_title.md +24 -0
- data/docs/_modules/custom.md +61 -0
- data/docs/_modules/helper_methods.md +10 -0
- data/docs/_modules/interface.md +66 -0
- data/docs/_modules/processing.md +7 -0
- data/docs/_modules/processing_proxy.md +28 -0
- data/docs/_objects/class/class.md +7 -0
- data/docs/_objects/global/global.md +7 -0
- data/docs/_objects/instance/instance.md +74 -0
- data/docs/_objects/numeric/numeric.md +37 -0
- data/docs/_posts/2018-05-06-getting_started.md +60 -0
- data/docs/_posts/2018-05-06-processing-api.md +68 -0
- data/docs/_posts/2018-05-11-arch-linux-arm.md +17 -0
- data/docs/about.md +7 -1
- data/docs/classes.md +10 -0
- data/docs/editors.md +10 -0
- data/docs/gems.md +11 -0
- data/docs/libraries.md +20 -0
- data/docs/magic.md +11 -0
- data/docs/methods.md +10 -0
- data/docs/modules.md +12 -0
- data/docs/objects.md +9 -0
- data/lib/picrate/version.rb +1 -1
- data/lib/picrate-0.0.3.jar +0 -0
- data/picrate.gemspec +2 -2
- data/pom.rb +1 -1
- data/pom.xml +7 -7
- data/src/main/java/monkstone/MathToolModule.java +2 -2
- data/src/main/java/monkstone/videoevent/VideoInterface.java +1 -1
- data/src/main/java/processing/core/PApplet.java +3 -3
- data/src/main/java/processing/javafx/PGraphicsFX2D.java +1 -1
- data/test/respond_to_test.rb +4 -4
- data/test/sketches/key_event.rb +3 -3
- data/vendors/Rakefile +1 -1
- metadata +61 -4
- data/lib/picrate-0.0.2.jar +0 -0
@@ -0,0 +1,57 @@
|
|
1
|
+
---
|
2
|
+
layout: post
|
3
|
+
title: "gems<sup>4</sup>"
|
4
|
+
keywords: library, gem
|
5
|
+
permalink: libraries/gems.html
|
6
|
+
---
|
7
|
+
The most convenient library to use in `ruby` is a `gem`, and `picrate` is no different, however in addition to pure `ruby gems` there are a number of `gems` that are wrappers for `java` libraries that can be used in `picrate`:-
|
8
|
+
|
9
|
+
#### ArcBall gem
|
10
|
+
|
11
|
+
This library is installed as a `picrate` dependency, and is used in 3D sketches to provide arcball manipulation of a 3D object (using quaternions in java).
|
12
|
+
|
13
|
+
```ruby
|
14
|
+
require 'arcball'
|
15
|
+
|
16
|
+
class MySketch
|
17
|
+
...
|
18
|
+
def setup
|
19
|
+
...
|
20
|
+
Processing::ArcBall.init(self)
|
21
|
+
...
|
22
|
+
|
23
|
+
```
|
24
|
+
|
25
|
+
In the above snippet the sketch viewport is centered at half width and half height of the sketch, which is also the center of rotation. Manipulate the object in the sketch center by dragging the mouse in direction of rotation, or us the mousewheel to zoom.
|
26
|
+
|
27
|
+
#### Toxiclibs gem
|
28
|
+
|
29
|
+
Is a ruby wrapper around Karsten Schmidts (aka toxi / postspectacular) toxiclibs libraries, in `picrate` you should prefer to use this collection of libraries as a `gem`. The toxiclibs libraries are a set of building blocks for computational design, that were designed to be compatible with processing-2.2.1 (and earlier versions of java). The [gem][toxi] is maintained independently from the version available in the processing ide, and the java code has been updated to make use java-8 and to be compatible with `processing-3.3.7` and hence `picrate`. The gem also provides a convenient [namespaces][ntoxi] for the toxiclibs libraries see [examples sketches][texamples], so you don't have to individualy import the java classes/packages.
|
30
|
+
|
31
|
+
#### Geomerative gem
|
32
|
+
|
33
|
+
Is a ruby wrapper around Ricard Marxer (@rikrd @ricardmp) [geomerative library][geomerative]. It extends 2D geometry operations to facilitate generative geometry. Includes a TrueType font and an SVG interpreters. See the [gem here][geomgem], which has been updated for java-8 and under the hood imports for Geomerative classes, so that you don't have to.
|
34
|
+
|
35
|
+
#### PBox2D gem
|
36
|
+
|
37
|
+
Is a java and ruby wrapper around Daniel Murphy (@dmurph) JBox2D library (_JBox2D is a close Java port of Erin Catto's excellent C++ Box2D physics engine and Google's LiquidFun physics Engine._). The java wrapper provides an interface between the processing and game physics worlds.
|
38
|
+
|
39
|
+
#### Wordcram gem
|
40
|
+
|
41
|
+
Is a ruby wrapper around the [Wordcram library][wordcram] by Dan Bernier, that can be used to create world clouds in JRubyArt or picrate. See [documentation][docu].
|
42
|
+
|
43
|
+
### Raytracing gem
|
44
|
+
|
45
|
+
The [joonsrenderer gem][joons] can be used to ray trace 3D objects in processing sketches. Includes an updated to java-8 version of the java [sunflow library][sunflow], and uses a more up to date version of the [janino compiler][janino].
|
46
|
+
|
47
|
+
|
48
|
+
[janino]:http://janino-compiler.github.io/janino/
|
49
|
+
[sunflow]:http://sunflow.sourceforge.net/
|
50
|
+
[joons]:https://ruby-processing.github.io/joonsrenderer/
|
51
|
+
[docu]:https://ruby-processing.github.io/
|
52
|
+
[wordcram]:http://wordcram.org/
|
53
|
+
[geomgem]:https://ruby-processing.github.io/geomerativegem/
|
54
|
+
[geomerative]:https://github.com/rikrd/geomerative
|
55
|
+
[ntoxi]:http://ruby-processing.github.io/toxicgem/namespace/
|
56
|
+
[toxi]:http://ruby-processing.github.io/toxicgem/toxiclibs/update/2015/11/28/introduction.html
|
57
|
+
[texamples]:https://github.com/ruby-processing/picrate-examples/tree/master/external_library/gem/toxiclibs
|
@@ -0,0 +1,9 @@
|
|
1
|
+
---
|
2
|
+
layout: post
|
3
|
+
title: "library_proxy<sup>2</sup>"
|
4
|
+
keywords: processing, abstract class, library
|
5
|
+
permalink: libraries/library_proxy.html
|
6
|
+
---
|
7
|
+
For advanced users only, we have created a `library_proxy` library that give access to vanilla processing [library methods][library] for more details see classes section.
|
8
|
+
|
9
|
+
[library]:https://github.com/processing/processing/wiki/Library-Basics
|
@@ -0,0 +1,511 @@
|
|
1
|
+
---
|
2
|
+
layout: post
|
3
|
+
title: "picrate<sup>1, 2</sup>"
|
4
|
+
keywords: library, boids, control_panel
|
5
|
+
permalink: libraries/picrate.html
|
6
|
+
---
|
7
|
+
Propane provides a number of libraries that you can use _out of the box_, but which still need to be loaded to use them in you sketches see examples below:-
|
8
|
+
|
9
|
+
|
10
|
+
### Boids library ###
|
11
|
+
<sup>1</sup><i>A built in pure ruby library</i>
|
12
|
+
|
13
|
+
The [original boids library][original] was created by Jeremy Ashkenas to demonstrate a pure 'ruby' library for ruby processing, this updated version has the same goal. However it is updated to make use of [Vec3D][vec3d] and [Vec2D][vec2d] classes (picrate features) and keyword arguments (ruby-2.1). It also use [forwardable][forwardable]. To see usage of now correctly implemented `angle` (heading) see [simple example][example].
|
14
|
+
|
15
|
+
See the full library code below:-
|
16
|
+
|
17
|
+
```ruby
|
18
|
+
# frozen_string_literal: true
|
19
|
+
# Boids -- after Tom de Smedt.
|
20
|
+
# See his Python version: http://nodebox.net/code/index.php/Boids
|
21
|
+
# This is an example of how a pure-Ruby library can work. Original for
|
22
|
+
# ruby-processing Jeremy Ashkenas. Reworked, re-factored for picrate
|
23
|
+
# by Martin Prout, features forwardable, keyword args, Vec3D and Vec2D.
|
24
|
+
class Boid
|
25
|
+
attr_reader :boids
|
26
|
+
attr_accessor :vel, :pos, :is_perching, :perch_time
|
27
|
+
def initialize(boids, pos)
|
28
|
+
@boids, @flock = boids, boids
|
29
|
+
@pos = pos
|
30
|
+
@vel = Vec3D.new
|
31
|
+
@is_perching = false
|
32
|
+
@perch_time = 0.0
|
33
|
+
end
|
34
|
+
|
35
|
+
def cohesion(d:)
|
36
|
+
# Boids gravitate towards the center of the flock,
|
37
|
+
# Which is the averaged position of the rest of the boids.
|
38
|
+
vect = Vec3D.new
|
39
|
+
@boids.each do |boid|
|
40
|
+
vect += boid.pos unless boid == self
|
41
|
+
end
|
42
|
+
count = @boids.length - 1.0
|
43
|
+
vect /= count
|
44
|
+
(vect - pos) / d
|
45
|
+
end
|
46
|
+
|
47
|
+
def separation(radius:)
|
48
|
+
# Boids don't like to cuddle.
|
49
|
+
vect = Vec3D.new
|
50
|
+
@boids.each do |boid|
|
51
|
+
if boid != self
|
52
|
+
dv = pos - boid.pos
|
53
|
+
vect += dv if dv.mag < radius
|
54
|
+
end
|
55
|
+
end
|
56
|
+
vect
|
57
|
+
end
|
58
|
+
|
59
|
+
def alignment(d:)
|
60
|
+
# Boids like to fly at the speed of traffic.
|
61
|
+
vect = Vec3D.new
|
62
|
+
@boids.each do |boid|
|
63
|
+
vect += boid.vel if boid != self
|
64
|
+
end
|
65
|
+
count = @boids.length - 1.0
|
66
|
+
vect /= count
|
67
|
+
(vect - vel) / d
|
68
|
+
end
|
69
|
+
|
70
|
+
def limit(max:)
|
71
|
+
# Tweet, Tweet! The boid police will bust you for breaking the speed limit.
|
72
|
+
most = [vel.x.abs, vel.y.abs, vel.z.abs].max
|
73
|
+
return if most < max
|
74
|
+
scale = max / most.to_f
|
75
|
+
@vel *= scale
|
76
|
+
end
|
77
|
+
|
78
|
+
def angle
|
79
|
+
Vec2D.new(vel.x, vel.y).heading
|
80
|
+
end
|
81
|
+
|
82
|
+
def goal(target, d = 50.0)
|
83
|
+
# Them boids is hungry.
|
84
|
+
(target - pos) / d
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
require 'forwardable'
|
89
|
+
|
90
|
+
# The Boids class
|
91
|
+
class Boids
|
92
|
+
include Enumerable
|
93
|
+
extend Forwardable
|
94
|
+
def_delegators(:@boids, :reject, :<<, :each, :shuffle!, :length, :next)
|
95
|
+
|
96
|
+
attr_reader :has_goal, :perch, :perch_tm, :perch_y
|
97
|
+
|
98
|
+
def initialize
|
99
|
+
@boids = []
|
100
|
+
end
|
101
|
+
|
102
|
+
def self.flock(n:, x:, y:, w:, h:)
|
103
|
+
flock = Boids.new.setup(n, x, y, w, h)
|
104
|
+
flock.reset_goal(Vec3D.new(w / 2, h / 2, 0))
|
105
|
+
end
|
106
|
+
|
107
|
+
def setup(n, x, y, w, h)
|
108
|
+
n.times do
|
109
|
+
dx, dy = rand(w), rand(h)
|
110
|
+
z = rand(200.0)
|
111
|
+
self << Boid.new(self, Vec3D.new(x + dx, y + dy, z))
|
112
|
+
end
|
113
|
+
@x, @y, @w, @h = x, y, w, h
|
114
|
+
@scattered = false
|
115
|
+
@scatter = 0.005
|
116
|
+
@scatter_time = 50.0
|
117
|
+
@scatter_i = 0.0
|
118
|
+
@perch = 1.0 # Lower this number to divebomb.
|
119
|
+
@perch_y = h
|
120
|
+
@perch_tm = -> { 25.0 + rand(50.0) }
|
121
|
+
@has_goal = false
|
122
|
+
@flee = false
|
123
|
+
@goal = Vec3D.new
|
124
|
+
self
|
125
|
+
end
|
126
|
+
|
127
|
+
def scatter(chance = 0.005, frames = 50.0)
|
128
|
+
@scatter = chance
|
129
|
+
@scatter_time = frames
|
130
|
+
end
|
131
|
+
|
132
|
+
def no_scatter
|
133
|
+
@scatter = 0.0
|
134
|
+
end
|
135
|
+
|
136
|
+
def perch(ground = nil, chance = 1.0, frames = nil)
|
137
|
+
@perch_tm = frames.nil? ? -> { 25.0 + rand(50.0) } : frames
|
138
|
+
@perch_y = ground.nil? ? @h : ground
|
139
|
+
@perch = chance
|
140
|
+
end
|
141
|
+
|
142
|
+
def no_perch
|
143
|
+
@perch = 0.0
|
144
|
+
end
|
145
|
+
|
146
|
+
def reset_goal(target)
|
147
|
+
@has_goal = true
|
148
|
+
@flee = false
|
149
|
+
@goal = target
|
150
|
+
self
|
151
|
+
end
|
152
|
+
|
153
|
+
def goal(target:, flee:)
|
154
|
+
@has_goal = true
|
155
|
+
@flee = flee
|
156
|
+
@goal = target
|
157
|
+
self
|
158
|
+
end
|
159
|
+
|
160
|
+
def no_goal
|
161
|
+
@has_goal = false
|
162
|
+
end
|
163
|
+
|
164
|
+
def constrain
|
165
|
+
# Put them boids in a cage.
|
166
|
+
dx, dy = @w * 0.1, @h * 0.1
|
167
|
+
each do |b|
|
168
|
+
b.vel.x += rand(dx) if b.pos.x < @x - dx
|
169
|
+
b.vel.y += rand(dy) if b.pos.y < @y - dy
|
170
|
+
b.vel.x -= rand(dx) if b.pos.x > @x + @w + dx
|
171
|
+
b.vel.y -= rand(dy) if b.pos.y > @y + @h + dy
|
172
|
+
b.vel.z += 10.0 if b.pos.z < 0.0
|
173
|
+
b.vel.z -= 10.0 if b.pos.z > 100.0
|
174
|
+
next unless b.pos.y > perch_y && rand < perch
|
175
|
+
b.pos.y = perch_y
|
176
|
+
b.vel.y = b.vel.y.abs * -0.2
|
177
|
+
b.is_perching = true
|
178
|
+
b.perch_time = perch_tm.respond_to?(:call) ? perch_tm.call : perch_tm
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
def update(goal: 20.0, limit: 30.0, **args)
|
183
|
+
shuffled = args.fetch(:shuffled, true)
|
184
|
+
cohesion = args.fetch(:cohesion, 100)
|
185
|
+
separation = args.fetch(:separation, 10)
|
186
|
+
alignment = args.fetch(:alignment, 5.0)
|
187
|
+
# Just flutter, little boids ... just flutter away.
|
188
|
+
# Shuffling keeps things flowing smooth.
|
189
|
+
shuffle! if shuffled
|
190
|
+
m1 = 1.0 # cohesion
|
191
|
+
m2 = 1.0 # separation
|
192
|
+
m3 = 1.0 # alignment
|
193
|
+
m4 = 1.0 # goal
|
194
|
+
@scattered = true if !@scattered && rand < @scatter
|
195
|
+
if @scattered
|
196
|
+
m1 = -m1
|
197
|
+
m3 *= 0.25
|
198
|
+
@scatter_i += 1.0
|
199
|
+
end
|
200
|
+
if @scatter_i >= @scatter_time
|
201
|
+
@scattered = false
|
202
|
+
@scatter_i = 0.0
|
203
|
+
end
|
204
|
+
m4 = 0.0 unless has_goal
|
205
|
+
m4 = -m4 if @flee
|
206
|
+
each do |b|
|
207
|
+
if b.is_perching
|
208
|
+
if b.perch_time > 0.0
|
209
|
+
b.perch_time -= 1.0
|
210
|
+
next
|
211
|
+
else
|
212
|
+
b.is_perching = false
|
213
|
+
end
|
214
|
+
end
|
215
|
+
v1 = b.cohesion(d: cohesion)
|
216
|
+
v2 = b.separation(radius: separation)
|
217
|
+
v3 = b.alignment(d: alignment)
|
218
|
+
v4 = b.goal(@goal, goal)
|
219
|
+
# NB: vector must precede scalar in '*' operation below
|
220
|
+
b.vel += (v1 * m1 + v2 * m2 + v3 * m3 + v4 * m4)
|
221
|
+
b.limit(max: limit)
|
222
|
+
b.pos += b.vel
|
223
|
+
end
|
224
|
+
constrain
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
```
|
229
|
+
|
230
|
+
Here is the re-factored Flight Patterns Sketch:-
|
231
|
+
```ruby
|
232
|
+
#!/usr/bin/env jruby -v -w
|
233
|
+
# Description:
|
234
|
+
# Flight Patterns is that ol' Euruko 2008 demo.
|
235
|
+
# Reworked version for Propane
|
236
|
+
# Usage:
|
237
|
+
# Drag mouse to steer 'invisible' flock attractor, use 'f' key to toggle flee
|
238
|
+
# Mouse 'click' to toggle 'sphere' or 'circle' display
|
239
|
+
require 'picrate'
|
240
|
+
|
241
|
+
class FlightPatterns < Processing::App
|
242
|
+
load_library :boids
|
243
|
+
|
244
|
+
attr_reader :flee, :radius
|
245
|
+
|
246
|
+
def settings
|
247
|
+
size 1024, 768, P3D
|
248
|
+
end
|
249
|
+
|
250
|
+
def setup
|
251
|
+
sketch_title 'Flight Patterns'
|
252
|
+
sphere_detail 8
|
253
|
+
color_mode RGB, 1.0
|
254
|
+
no_stroke
|
255
|
+
shininess 1.0
|
256
|
+
specular 0.3, 0.1, 0.1
|
257
|
+
emissive 0.03, 0.03, 0.1
|
258
|
+
@radius = 0.02 * height
|
259
|
+
@click = false
|
260
|
+
@flee = false
|
261
|
+
@flocks = (0..3).map { Boids.flock(n: 20, x: 0, y: 0, w: width, h: height) }
|
262
|
+
end
|
263
|
+
|
264
|
+
def mouse_pressed
|
265
|
+
@click = !@click
|
266
|
+
end
|
267
|
+
|
268
|
+
def key_pressed
|
269
|
+
return unless key == 'f'
|
270
|
+
@flee = !@flee
|
271
|
+
end
|
272
|
+
|
273
|
+
def draw
|
274
|
+
background 0.05
|
275
|
+
ambient_light 0.01, 0.01, 0.01
|
276
|
+
light_specular 0.4, 0.2, 0.2
|
277
|
+
point_light 1.0, 1.0, 1.0, mouse_x, mouse_y, 190
|
278
|
+
@flocks.each_with_index do |flock, i|
|
279
|
+
flock.goal(target: Vec3D.new(mouse_x, mouse_y, 0), flee: @flee)
|
280
|
+
flock.update(goal: 185, limit: 13.5)
|
281
|
+
flock.each do |boid|
|
282
|
+
r = (0.15 * boid.pos.z) + radius
|
283
|
+
case i
|
284
|
+
when 0 then fill 0.85, 0.65, 0.65
|
285
|
+
when 1 then fill 0.65, 0.85, 0.65
|
286
|
+
when 2 then fill 0.65, 0.65, 0.85
|
287
|
+
end
|
288
|
+
push_matrix
|
289
|
+
point_array = (boid.pos.to_a).map { |p| p - (r / 2.0) }
|
290
|
+
translate(*point_array)
|
291
|
+
@click ? sphere(r / 2) : ellipse(0, 0, r, r)
|
292
|
+
@click ? hint(ENABLE_DEPTH_TEST) : hint(DISABLE_DEPTH_TEST)
|
293
|
+
pop_matrix
|
294
|
+
end
|
295
|
+
end
|
296
|
+
end
|
297
|
+
end
|
298
|
+
|
299
|
+
FlightPatterns.new
|
300
|
+
|
301
|
+
```
|
302
|
+
|
303
|
+
|
304
|
+
### Control Panel library
|
305
|
+
|
306
|
+
<sup>2</sup><i>A built in hybrid ruby/java library</i>
|
307
|
+
|
308
|
+
Start by loading in the control_panel library, and then define your panel in setup like so:
|
309
|
+
|
310
|
+
```ruby
|
311
|
+
#!/usr/bin/env jruby -v -W2
|
312
|
+
# frozen_string_literal: true
|
313
|
+
require 'picrate'
|
314
|
+
# Iconic ruby-processing example for Propane
|
315
|
+
class JWishy < Processing::App
|
316
|
+
load_library :control_panel
|
317
|
+
|
318
|
+
attr_reader :alpha, :back_color, :bluish, :hide, :magnitude, :panel
|
319
|
+
attr_reader :x_wiggle, :y_wiggle, :go_big, :shape
|
320
|
+
|
321
|
+
def settings
|
322
|
+
size 600, 600
|
323
|
+
end
|
324
|
+
|
325
|
+
def setup
|
326
|
+
sketch_title 'Wishy Worm'
|
327
|
+
control_panel do |c|
|
328
|
+
c.title 'Control Panel'
|
329
|
+
c.look_feel 'Nimbus'
|
330
|
+
c.slider :bluish, 0.0..1.0, 0.5
|
331
|
+
c.slider :alpha, 0.0..1.0, 0.5
|
332
|
+
c.checkbox :go_big, false
|
333
|
+
c.button :reset
|
334
|
+
c.menu :shape, %w[oval square triangle], 'oval'
|
335
|
+
@panel = c
|
336
|
+
end
|
337
|
+
@hide = false
|
338
|
+
@x_wiggle, @y_wiggle = 10.0, 0
|
339
|
+
@magnitude = 8.15
|
340
|
+
@back_color = [0.06, 0.03, 0.18]
|
341
|
+
color_mode RGB, 1
|
342
|
+
ellipse_mode CORNER
|
343
|
+
smooth
|
344
|
+
end
|
345
|
+
|
346
|
+
#....rest of code
|
347
|
+
|
348
|
+
|
349
|
+
def draw
|
350
|
+
# only make control_panel visible once, or again when hide is false
|
351
|
+
unless hide
|
352
|
+
@hide = true
|
353
|
+
panel.set_visible(hide)
|
354
|
+
end
|
355
|
+
#.... rest of draw
|
356
|
+
|
357
|
+
JWishy.new
|
358
|
+
|
359
|
+
|
360
|
+
```
|
361
|
+
![JWishy]({{site.github.url}}/assets/jwishy.png)
|
362
|
+
|
363
|
+
See also [penrose](https://github.com/ruby-processing/picrate-examples/blob/master/library/vecmath/vec2d/penrose.rb) and [bezier playground](https://github.com/ruby-processing/picrate-examples/blob/master/contributed/bezier_playground.rb) sketches. See ruby code [here](https://github.com/ruby-processing/picrate/blob/master/library/control_panel/control_panel.rb).
|
364
|
+
|
365
|
+
### Video Event Library ###
|
366
|
+
|
367
|
+
<sup>2</sup><i>A built in hybrid ruby/java library</i>
|
368
|
+
The video library should be installed using `picrate --install video`
|
369
|
+
|
370
|
+
The purpose of the `video_event` library is to allow you to use the vanilla processing reflection methods `captureEvent` and `movieEvent` from the processing `video` library. _It is almost impossible to use vanilla processing reflection methods without this sort of wrapper_.
|
371
|
+
|
372
|
+
If MacOS users experience difficulty with the video library they should probably rename the binary folder from `macosx64` to `macosx`. However it seems as though the binaries get dynamically loaded from the video library, and this may not be necessary see [Line 178][178] (personal communication Gottfreid Haider) but this is pure conjecture in case of picrate.
|
373
|
+
|
374
|
+
A movie example:-
|
375
|
+
|
376
|
+
```ruby
|
377
|
+
#!/usr/bin/env jruby -w
|
378
|
+
require 'picrate'
|
379
|
+
# Loop.
|
380
|
+
#
|
381
|
+
# Shows how to load and play a QuickTime movie file.
|
382
|
+
class Loop < Processing::App
|
383
|
+
load_libraries :video, :video_event
|
384
|
+
include_package 'processing.video'
|
385
|
+
|
386
|
+
attr_reader :movie
|
387
|
+
|
388
|
+
def setup
|
389
|
+
sketch_title 'Loop'
|
390
|
+
background(0)
|
391
|
+
# Load and play the video in a loop
|
392
|
+
@movie = Movie.new(self, data_path('transit.mov'))
|
393
|
+
movie.loop
|
394
|
+
end
|
395
|
+
|
396
|
+
def draw
|
397
|
+
image(movie, 0, 0, width, height)
|
398
|
+
end
|
399
|
+
|
400
|
+
# use camel case to match java reflect method
|
401
|
+
def movieEvent(m)
|
402
|
+
m.read
|
403
|
+
end
|
404
|
+
|
405
|
+
def settings
|
406
|
+
size 640, 360
|
407
|
+
end
|
408
|
+
end
|
409
|
+
|
410
|
+
Loop.new
|
411
|
+
```
|
412
|
+
|
413
|
+
A capture example-
|
414
|
+
|
415
|
+
```ruby
|
416
|
+
#!/usr/bin/env jruby -w
|
417
|
+
require 'picrate'
|
418
|
+
class TestCapture < Processing::App
|
419
|
+
load_libraries :video, :video_event
|
420
|
+
|
421
|
+
include_package 'processing.video'
|
422
|
+
|
423
|
+
attr_reader :cam
|
424
|
+
|
425
|
+
def setup
|
426
|
+
sketch_title 'Test Capture'
|
427
|
+
cameras = Capture.list
|
428
|
+
fail 'There are no cameras available for capture.' if (cameras.length == 0)
|
429
|
+
p 'Matching cameras available:'
|
430
|
+
size_pattern = Regexp.new(format('%dx%d', width, height))
|
431
|
+
select = cameras.grep size_pattern # filter available cameras
|
432
|
+
select.uniq.map { |cam| p cam.strip }
|
433
|
+
fail 'There are no matching cameras.' if (select.length == 0)
|
434
|
+
start_capture(select[0])
|
435
|
+
end
|
436
|
+
|
437
|
+
def start_capture(cam_string)
|
438
|
+
# The camera can be initialized directly using an
|
439
|
+
# element from the array returned by list:
|
440
|
+
@cam = Capture.new(self, cam_string)
|
441
|
+
p format('Using camera %s', cam_string)
|
442
|
+
cam.start
|
443
|
+
end
|
444
|
+
|
445
|
+
def draw
|
446
|
+
image(cam, 0, 0, width, height)
|
447
|
+
# The following does the same, and is faster when just drawing the image
|
448
|
+
# without any additional resizing, transformations, or tint.
|
449
|
+
# set(0, 0, cam)
|
450
|
+
end
|
451
|
+
|
452
|
+
def captureEvent(c)
|
453
|
+
c.read
|
454
|
+
end
|
455
|
+
|
456
|
+
def settings
|
457
|
+
size 1280, 720, P2D
|
458
|
+
end
|
459
|
+
end
|
460
|
+
|
461
|
+
TestCapture.new
|
462
|
+
```
|
463
|
+
|
464
|
+
### File Chooser Library ###
|
465
|
+
|
466
|
+
<sup>2</sup><i>A built in hybrid ruby/java library</i>
|
467
|
+
|
468
|
+
Start by loading in the chooser library, the purpose of this library is to allow you to use the vanilla processing interface to the `native file chooser` (it is almost impossible to use vanilla processing reflection methods without this sort of wrapper)
|
469
|
+
|
470
|
+
```ruby
|
471
|
+
#!/usr/bin/env jruby -v -W2
|
472
|
+
|
473
|
+
require 'picrate'
|
474
|
+
###########
|
475
|
+
# Example Native File Chooser using vanilla processing
|
476
|
+
# select_input, and file_selected
|
477
|
+
###########
|
478
|
+
class SelectFile < Processing::App
|
479
|
+
|
480
|
+
load_library :file_chooser
|
481
|
+
|
482
|
+
|
483
|
+
def settings
|
484
|
+
size 200, 100
|
485
|
+
end
|
486
|
+
|
487
|
+
def setup
|
488
|
+
sketch_title 'Select File, native chooser'
|
489
|
+
# java_signature 'void selectInput(String, String)'
|
490
|
+
select_input('Select a File', 'file_selected')
|
491
|
+
end
|
492
|
+
|
493
|
+
# signature 'void file_selected(java.io.File file)'
|
494
|
+
def file_selected(file)
|
495
|
+
puts file.get_absolute_path unless file.nil?
|
496
|
+
end
|
497
|
+
end
|
498
|
+
|
499
|
+
SelectFile.new
|
500
|
+
```
|
501
|
+
|
502
|
+
See also [these examples](https://github.com/ruby-processing/picrate-examples/tree/master/processing_app/library/file_chooser)
|
503
|
+
|
504
|
+
[178]:https://github.com/processing/processing-video/blob/master/src/processing/video/Video.java
|
505
|
+
|
506
|
+
|
507
|
+
[original]:https://github.com/jashkenas/ruby-processing/blob/8865c934318e05e62cbfa2603e661275b1cffd31/library/boids/boids.rb
|
508
|
+
[vec3d]:https://ruby-processing.github.io/classes/vec3d/
|
509
|
+
[vec2d]:https://ruby-processing.github.io/classes/vec2d/
|
510
|
+
[forwardable]:https://ruby-doc.org/stdlib-2.0.0/libdoc/forwardable/rdoc/Forwardable.html
|
511
|
+
[example]:https://github.com/ruby-processing/picrate-examples/blob/master/library/boids/boids_example.rb
|
@@ -0,0 +1,126 @@
|
|
1
|
+
---
|
2
|
+
layout: post
|
3
|
+
title: "processing<sup>5</sup>"
|
4
|
+
keywords: library, boids, control_panel
|
5
|
+
permalink: libraries/processing.html
|
6
|
+
---
|
7
|
+
### Sound library ###
|
8
|
+
|
9
|
+
<sup>5</sup><i>A vanilla processing (java) library</i>
|
10
|
+
|
11
|
+
First load the sound library (assumes it was installed using `picrate --install Sound`)
|
12
|
+
|
13
|
+
You might just as well `include_package` to get namespace access to the `processing.sound` package.
|
14
|
+
|
15
|
+
Note processing currently supports only 32 bit drivers on raspberrypi, and we assume 64 bit on regular linux.
|
16
|
+
|
17
|
+
```ruby
|
18
|
+
# This is a simple pink noise generator. It can be started with .play(amp).
|
19
|
+
# In this example it is started and stopped by clicking into the renderer window.
|
20
|
+
require 'picrate'
|
21
|
+
|
22
|
+
class PinkNoiseApp < Processing::App
|
23
|
+
load_library :sound
|
24
|
+
include_package 'processing.sound'
|
25
|
+
|
26
|
+
attr_reader :amp, :noise
|
27
|
+
|
28
|
+
def settings
|
29
|
+
size(640, 360)
|
30
|
+
end
|
31
|
+
|
32
|
+
def setup
|
33
|
+
sketch_title 'Pink Noise'
|
34
|
+
background(255)
|
35
|
+
@amp = 0.0
|
36
|
+
# Create the noise generator
|
37
|
+
@noise = PinkNoise.new(self)
|
38
|
+
noise.play(amp)
|
39
|
+
end
|
40
|
+
|
41
|
+
def draw
|
42
|
+
# Map mouseX from 0.0 to 1.0 for amplitude
|
43
|
+
noise.amp(map1d(mouse_x, (0..width), (0.0..1.0)))
|
44
|
+
# Map mouseY from -1.0 to 1.0 for left to right
|
45
|
+
noise.pan(map1d(mouse_y, (0..height), (-1.0..1.0)))
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
PinkNoiseApp.new
|
50
|
+
```
|
51
|
+
|
52
|
+
### Listing vanilla processing contributed libraries and their urls ###
|
53
|
+
|
54
|
+
```bash
|
55
|
+
wget http://download.processing.org/contribs/contribs.txt
|
56
|
+
```
|
57
|
+
|
58
|
+
### Installing contributed vanilla processing libraries ###
|
59
|
+
|
60
|
+
Install libraries to your `~/.picrate/libraries` folder. NB: this created for you when you install the `glvideo` or `sound` libraries. The one unfortunate / fortunate thing is that you will be responsible for updating versions manually (can be good / bad thing).
|
61
|
+
|
62
|
+
```bash
|
63
|
+
picrate -i Sound
|
64
|
+
picrate -i Video
|
65
|
+
picrate -i glvideo
|
66
|
+
```
|
67
|
+
|
68
|
+
It can make sense to convert the library names and jars from `camelcase` to `snakecase`, (_ie when library creators have messed up_) but just be to be consistent, as example below
|
69
|
+
|
70
|
+
```bash
|
71
|
+
cd ~/.picrate/libraries
|
72
|
+
wget http://staff.city.ac.uk/~jwo/giCentre/utils/gicentreUtils.zip
|
73
|
+
unzip gicentreUtils.zip # NB: British English spelling of centre
|
74
|
+
mv gicentreUtils gicenter_utils # Use snake case, and convert spelling
|
75
|
+
cd gicenter_utils/library
|
76
|
+
mv gicentreUtils.jar gicenter_utils.jar
|
77
|
+
```
|
78
|
+
Here is an example sketch translated to picrate, main differences are how we load libraries and access package namespace in picrate. Also note the use of the data_path wrapper to access sketch data folder. Another twist is the need to cast array of ruby Numbers to java float.
|
79
|
+
|
80
|
+
```ruby
|
81
|
+
require 'picrate'
|
82
|
+
# Sketch to demonstrate the use of the BarChart class to draw simple bar charts.
|
83
|
+
# Version 1.3, 6th February, 2016.
|
84
|
+
# Author Jo Wood, giCentre.
|
85
|
+
class BarChartSketch < Processing::App
|
86
|
+
load_library :gicenter_utils
|
87
|
+
include_package 'org.gicentre.utils.stat' # British spelling
|
88
|
+
|
89
|
+
def settings
|
90
|
+
size(800, 300)
|
91
|
+
smooth
|
92
|
+
end
|
93
|
+
|
94
|
+
def setup # a static sketch no need for draw loop
|
95
|
+
sketch_title 'Bar Chart Sketch'
|
96
|
+
title_font = load_font(data_path('Helvetica-22.vlw'))
|
97
|
+
small_font = load_font(data_path('Helvetica-12.vlw'))
|
98
|
+
text_font(small_font)
|
99
|
+
bar_chart = BarChart.new(self)
|
100
|
+
data_float = [
|
101
|
+
2_462, 2_801, 3_280, 3_983, 4_490, 4_894, 5_642, 6_322, 6_489, 6_401,
|
102
|
+
7_657, 9_649, 9_767, 12_167, 15_154, 18_200, 23_124, 28_645, 39_471
|
103
|
+
]
|
104
|
+
bar_chart.setData(data_float.to_java(:float))
|
105
|
+
data_label = %w(1830 1840 1850 1860 1870 1880 1890 1900 1910 1920 1930 1940 1950 1960 1970 1980 1990 2000 2010)
|
106
|
+
bar_chart.setBarLabels(data_label)
|
107
|
+
bar_chart.setBarColour(color(200, 80, 80, 100))
|
108
|
+
bar_chart.setBarGap(2)
|
109
|
+
bar_chart.setValueFormat('$###,###')
|
110
|
+
bar_chart.showValueAxis(true)
|
111
|
+
bar_chart.showCategoryAxis(true)
|
112
|
+
background(255)
|
113
|
+
bar_chart.draw(10, 10, width - 20, height - 20)
|
114
|
+
fill(120)
|
115
|
+
text_font(title_font)
|
116
|
+
text('Income per person, United Kingdom', 70, 30)
|
117
|
+
text_height = text_ascent # of title font
|
118
|
+
text_font(small_font)
|
119
|
+
text('Gross domestic product measured in inflation-corrected $US', 70, 30 + text_height)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
BarChartSketch.new
|
124
|
+
```
|
125
|
+
|
126
|
+
![bar chart sketch]({{ site.github.url }}/assets/bar_chart.png)
|