ruby-processing 1.0.2 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. data/CHANGELOG +12 -0
  2. data/lib/ruby-processing.rb +2 -1
  3. data/lib/ruby-processing/app.rb +7 -5
  4. data/lib/ruby-processing/exporters/creator.rb +7 -4
  5. data/lib/ruby-processing/helpers/numeric.rb +11 -0
  6. data/lib/ruby-processing/helpers/string.rb +8 -0
  7. data/lib/ruby-processing/runner.rb +11 -10
  8. data/lib/ruby-processing/runners/watch.rb +33 -0
  9. data/samples/bezier_playground.rb +243 -0
  10. data/samples/flight_patterns.rb +1 -1
  11. data/samples/learning_processing/chapter_16/01_display_video.rb +1 -1
  12. data/samples/learning_processing/chapter_16/02_manipulate_video_image.rb +1 -1
  13. data/samples/processing_app/basics/arrays/array.rb +41 -0
  14. data/samples/processing_app/basics/arrays/array_2d.rb +38 -0
  15. data/samples/processing_app/basics/arrays/array_objects.rb +67 -0
  16. data/samples/processing_app/basics/color/brightness.rb +30 -0
  17. data/samples/processing_app/basics/color/color_wheel.rb +97 -0
  18. data/samples/processing_app/basics/color/creating.rb +37 -0
  19. data/samples/processing_app/basics/color/hue.rb +29 -0
  20. data/samples/processing_app/basics/color/linear_gradient.rb +47 -0
  21. data/samples/processing_app/basics/color/radial_gradient.rb +52 -0
  22. data/samples/processing_app/basics/color/reading/data/cait.jpg +0 -0
  23. data/samples/processing_app/basics/color/reading/reading.rb +43 -0
  24. data/samples/processing_app/basics/color/relativity.rb +38 -0
  25. data/samples/processing_app/basics/color/saturation.rb +35 -0
  26. data/samples/processing_app/basics/color/wave_gradient.rb +45 -0
  27. data/samples/processing_app/basics/control/conditionals1.rb +51 -0
  28. data/samples/processing_app/basics/control/conditionals2.rb +44 -0
  29. data/samples/processing_app/basics/control/embedded_iteration.rb +42 -0
  30. data/samples/processing_app/basics/control/iteration.rb +61 -0
  31. data/samples/processing_app/basics/control/logical_operators.rb +59 -0
  32. data/samples/processing_app/basics/data/characters_strings/characters_strings.rb +87 -0
  33. data/samples/processing_app/basics/data/characters_strings/data/Eureka-90.vlw +0 -0
  34. data/samples/processing_app/basics/data/characters_strings/data/rathausFrog.jpg +0 -0
  35. data/samples/processing_app/basics/data/datatype_conversion.rb +45 -0
  36. data/samples/processing_app/basics/data/integers_floats.rb +34 -0
  37. data/samples/processing_app/basics/data/true_false.rb +37 -0
  38. data/samples/processing_app/basics/data/variable_scope.rb +80 -0
  39. data/samples/processing_app/basics/data/variables.rb +40 -0
  40. data/samples/processing_app/basics/form/bezier.rb +23 -0
  41. data/samples/processing_app/basics/form/bezier_ellipse.rb +110 -0
  42. data/samples/processing_app/basics/form/pie_chart.rb +31 -0
  43. data/samples/processing_app/basics/form/points_lines.rb +37 -0
  44. data/samples/processing_app/basics/form/shape_primitives.rb +25 -0
  45. data/samples/processing_app/basics/form/triangle_strip.rb +43 -0
  46. data/samples/processing_app/basics/form/vertices.rb +51 -0
  47. data/samples/processing_app/basics/image/alphamask.rb +23 -0
  48. data/samples/processing_app/basics/image/background_image.rb +30 -0
  49. data/samples/processing_app/basics/image/create_image.rb +23 -0
  50. data/samples/processing_app/basics/image/data/construct.jpg +0 -0
  51. data/samples/processing_app/basics/image/data/eames.jpg +0 -0
  52. data/samples/processing_app/basics/image/data/jelly.jpg +0 -0
  53. data/samples/processing_app/basics/image/data/mask.jpg +0 -0
  54. data/samples/processing_app/basics/image/data/milan_rubbish.jpg +0 -0
  55. data/samples/processing_app/basics/image/data/teddy.gif +0 -0
  56. data/samples/processing_app/basics/image/data/test.jpg +0 -0
  57. data/samples/processing_app/basics/image/data/wash.jpg +0 -0
  58. data/samples/processing_app/basics/image/load_display_image.rb +25 -0
  59. data/samples/processing_app/basics/image/pointillism.rb +30 -0
  60. data/samples/processing_app/basics/image/request_image.rb +71 -0
  61. data/samples/processing_app/basics/image/sprite.rb +38 -0
  62. data/samples/processing_app/basics/image/transparency.rb +27 -0
  63. data/samples/processing_app/basics/input/clock.rb +46 -0
  64. data/samples/processing_app/basics/input/constrain.rb +39 -0
  65. data/samples/processing_app/basics/input/easing.rb +33 -0
  66. data/samples/processing_app/basics/input/keyboard.rb +36 -0
  67. data/samples/processing_app/basics/input/keyboard_2.rb +45 -0
  68. data/samples/processing_app/basics/input/keyboard_functions.rb +87 -0
  69. data/samples/processing_app/basics/input/milliseconds.rb +25 -0
  70. data/samples/processing_app/basics/input/mouse_1d.rb +34 -0
  71. data/samples/processing_app/basics/input/mouse_2d.rb +25 -0
  72. data/samples/processing_app/basics/input/mouse_functions.rb +73 -0
  73. data/samples/processing_app/basics/input/mouse_press.rb +21 -0
  74. data/samples/processing_app/basics/input/mouse_signals.rb +45 -0
  75. data/samples/processing_app/basics/input/storing_input.rb +39 -0
  76. data/samples/processing_app/basics/math/additive_wave.rb +66 -0
  77. data/samples/processing_app/basics/math/arctangent.rb +54 -0
  78. data/samples/processing_app/topics/simulate/chain.rb +82 -0
  79. data/samples/processing_app/topics/simulate/multiple_particle_systems.rb +166 -0
  80. data/samples/processing_app/topics/simulate/simple_particle_system.rb +113 -0
  81. data/samples/processing_app/topics/simulate/spring.rb +85 -0
  82. data/samples/processing_app/topics/simulate/springs.rb +125 -0
  83. metadata +93 -2
data/CHANGELOG CHANGED
@@ -1,3 +1,15 @@
1
+ v1.0.3 Tweaks and Tuneups...
2
+ * "rp5 watch" is now a bit more robust, and tries to reload every
3
+ * file, global, and constant that it thinks it needs to.
4
+ * Many, many examples have been contributed by Marc Chung,
5
+ Peter Krenn, and Florian Jenett.
6
+ * Andreas Haller contributed a patch that added Ruby-1.9 compatibility.
7
+ * The render mode now defaults to JAVA2D, as does Processing.
8
+ * "rp5 create" now informs you of the file it just created.
9
+ * "key" now returns a character, if ASCII and the integer value otherwise,
10
+ mirroring Processing's behavior.
11
+ * Numbers now have the methods 'degrees' and 'radians', for ease.
12
+
1
13
  v1.0.2 Bugfixes and Java Args...
2
14
  * Application exporting, long plagued, should now be a little
3
15
  closer to rock-solid. If you need to pass command-line options
@@ -8,10 +8,11 @@ unless defined? RP5_ROOT
8
8
  end
9
9
 
10
10
  require 'ruby-processing/helpers/string'
11
+ require 'ruby-processing/helpers/numeric'
11
12
 
12
13
  # The top-level namespace, a home for all Ruby-Processing classes.
13
14
  module Processing
14
- VERSION = [1,0,2]
15
+ VERSION = [1,0,3] unless defined? Processing::VERSION
15
16
 
16
17
  # Returns the current version of Ruby-Processing.
17
18
  def self.version
@@ -8,7 +8,7 @@ module Processing
8
8
 
9
9
  # Conditionally load core.jar
10
10
  require "#{RP5_ROOT}/lib/core/core.jar" unless Object.const_defined?(:JRUBY_APPLET)
11
- include_package "processing.core"
11
+ import "processing.core"
12
12
 
13
13
  # This is the main Ruby-Processing class, and is what you'll
14
14
  # inherit from when you create a sketch. This class can call
@@ -20,11 +20,11 @@ module Processing
20
20
  class App < PApplet
21
21
  include Math
22
22
 
23
- include_class "javax.swing.JFrame"
23
+ import "javax.swing.JFrame"
24
24
 
25
25
  # Include some processing classes that we'd like to use:
26
26
  %w(PShape PImage PGraphics PFont PVector).each do |klass|
27
- include_class "processing.core.#{klass}"
27
+ import "processing.core.#{klass}"
28
28
  end
29
29
 
30
30
  # Alias some methods for familiarity for Shoes coders.
@@ -175,7 +175,7 @@ module Processing
175
175
  :full_screen => false
176
176
  }.merge(options)
177
177
  @width, @height, @title = options[:width], options[:height], options[:title]
178
- @render_mode = P2D
178
+ @render_mode = JAVA2D
179
179
  determine_how_to_display options
180
180
  end
181
181
 
@@ -235,10 +235,12 @@ module Processing
235
235
 
236
236
 
237
237
  # Fix java conversion problems getting the last key
238
+ # If it's ASCII, return the character, otherwise the integer
238
239
  def key
239
240
  field = java_class.declared_field 'key'
240
241
  app = Java.ruby_to_java self
241
- field.value app
242
+ int = field.value(app)
243
+ int < 256 ? int.chr : int
242
244
  end
243
245
 
244
246
 
@@ -9,7 +9,10 @@ module Processing
9
9
  main_file = File.basename(path, ".rb")
10
10
  # Check to make sure that the main file exists
11
11
  already_exists = File.exists?(path) || File.exists?("#{File.dirname(path)}/#{main_file.underscore}.rb")
12
- puts "That sketch already exists." and exit if already_exists
12
+ if already_exists
13
+ puts "That sketch already exists."
14
+ exit
15
+ end
13
16
 
14
17
  # Get the substitutions
15
18
  @name = main_file.camelize
@@ -23,9 +26,9 @@ module Processing
23
26
  mkdir_p dir
24
27
  template = File.new("#{RP5_ROOT}/lib/templates/create/blank_sketch.rb.erb")
25
28
  rendered = render_erb_from_string_with_binding(template.read, binding)
26
- File.open(File.join(dir, "#{@file_name}.rb"), "w") do |file|
27
- file.print rendered
28
- end
29
+ full_path = File.join(dir, "#{@file_name}.rb")
30
+ File.open(full_path, "w") {|f| f.print(rendered) }
31
+ puts "Created Sketch \"#{@title}\" in #{full_path.sub(/\A\.\//, '')}"
29
32
  end
30
33
 
31
34
  # Show the help/usage message for create.
@@ -0,0 +1,11 @@
1
+ class Numeric #:nodoc
2
+
3
+ def degrees
4
+ self*180/Math::PI
5
+ end
6
+
7
+ def radians
8
+ self*Math::PI/180
9
+ end
10
+
11
+ end
@@ -24,4 +24,12 @@ class String #:nodoc:
24
24
  downcase
25
25
  end
26
26
 
27
+ # String.ord is Ruby 1.9, so this is a little fix for R 1.8
28
+ # to make it forward compatible and readable
29
+ unless String.method_defined? :ord
30
+ def ord
31
+ self[0]
32
+ end
33
+ end
34
+
27
35
  end
@@ -37,16 +37,17 @@ module Processing
37
37
  # Dispatch central.
38
38
  def execute!
39
39
  case @options.action
40
- when 'run' : run(@options.path)
41
- when 'watch' : watch(@options.path)
42
- when 'create' : create(@options.path, @options.args)
43
- when 'live' : live(@options.path)
44
- when 'app' : app(@options.path)
45
- when 'applet' : applet(@options.path)
46
- when 'unpack' : unpack(@options.path)
47
- when /-v/ : show_version
48
- when /-h/ : show_help
49
- else show_help
40
+ when 'run' then run(@options.path)
41
+ when 'watch' then watch(@options.path)
42
+ when 'create' then create(@options.path, @options.args)
43
+ when 'live' then live(@options.path)
44
+ when 'app' then app(@options.path)
45
+ when 'applet' then applet(@options.path)
46
+ when 'unpack' then unpack(@options.path)
47
+ when /-v/ then show_version
48
+ when /-h/ then show_help
49
+ else
50
+ show_help
50
51
  end
51
52
  end
52
53
 
@@ -10,10 +10,12 @@ module Processing
10
10
  def initialize(sketch)
11
11
  @file = sketch
12
12
  @time = Time.now
13
+ record_state_of_ruby
13
14
  load @file
14
15
  start_watching
15
16
  end
16
17
 
18
+
17
19
  # Kicks off a thread to watch the sketch, reloading Ruby-Processing
18
20
  # and restarting the sketch whenever it changes.
19
21
  def start_watching
@@ -23,6 +25,7 @@ module Processing
23
25
  if file_mtime > @time
24
26
  @time = file_mtime
25
27
  Processing::App.wipe_out_current_app!
28
+ rewind_to_recorded_state
26
29
  GC.start
27
30
  begin
28
31
  load @file
@@ -36,6 +39,36 @@ module Processing
36
39
  thread.join
37
40
  end
38
41
 
42
+
43
+ # Do the best we can to take a picture of the current Ruby interpreter.
44
+ # For now, this means top-level constants and loaded .rb files.
45
+ def record_state_of_ruby
46
+ @saved_constants = Object.send(:constants).dup
47
+ @saved_load_paths = $LOAD_PATH.dup
48
+ @saved_features = $LOADED_FEATURES.dup
49
+ @saved_globals = Kernel.global_variables.dup
50
+ end
51
+
52
+
53
+ # Try to go back to the recorded Ruby state.
54
+ def rewind_to_recorded_state
55
+ new_constants = Object.send(:constants).reject {|c| @saved_constants.include?(c) }
56
+ new_load_paths = $LOAD_PATH.reject {|p| @saved_load_paths.include?(p) }
57
+ new_features = $LOADED_FEATURES.reject {|f| @saved_features.include?(f) }
58
+ new_globals = Kernel.global_variables.reject {|g| @saved_globals.include?(g) }
59
+
60
+ new_constants.each {|c| Object.send(:remove_const, c) }
61
+ new_load_paths.each {|p| $LOAD_PATH.delete(p) }
62
+ new_features.each {|f| $LOADED_FEATURES.delete(f) }
63
+ new_globals.each do |g|
64
+ begin
65
+ eval("#{g} = nil") # There's no way to undef a global variable in Ruby
66
+ rescue NameError => e
67
+ # Some globals are read-only, and we can't set them to nil.
68
+ end
69
+ end
70
+ end
71
+
39
72
  end
40
73
  end
41
74
 
@@ -0,0 +1,243 @@
1
+ require 'ruby-processing'
2
+
3
+ # A Bezier playground. Click to shape the curve. Drag to move it.
4
+ # Arrows toggle between curves, delete removes them.
5
+ # You can print out the parametric equations for t = 0..1
6
+
7
+
8
+ module Math
9
+
10
+ def self.overlaps(x, y, point_x, point_y)
11
+ Math.sqrt((x-point_x)**2 + (y-point_y)**2) < Bezier::RADIUS
12
+ end
13
+
14
+ end
15
+
16
+
17
+ class Curve
18
+
19
+ attr_accessor :x1, :y1, :c1x, :c1y, :c2x, :c2y, :x2, :y2
20
+
21
+ def initialize
22
+ @x1, @y1, @x2, @y2 = Bezier::X1, Bezier::Y1, Bezier::X2, Bezier::Y2
23
+ set_control_points( Bezier::X1+30, Bezier::Y1, Bezier::X2-30, Bezier::Y2)
24
+ end
25
+
26
+
27
+ def contains(x, y)
28
+ return :one if Math.overlaps(@x1, @y1, x, y)
29
+ return :two if Math.overlaps(@x2, @y2, x, y)
30
+ end
31
+
32
+
33
+ def all_points
34
+ return x1, y1, c1x, c1y, c2x, c2y, x2, y2
35
+ end
36
+
37
+
38
+ def control_points
39
+ return c1x, c1y, c2x, c2y
40
+ end
41
+
42
+
43
+ def set_control_points(*points)
44
+ @c1x, @c1y, @c2x, @c2y = *points
45
+ end
46
+
47
+
48
+ def draw
49
+ $app.bezier *all_points
50
+ $app.oval @x1, @y1, 3, 3
51
+ $app.oval @x2, @y2, 3, 3
52
+ end
53
+
54
+
55
+ def print_equation
56
+ p = all_points.map {|p| p.to_i }
57
+ puts ""
58
+ puts "*** line ##{$app.curves.index(self) + 1} ***"
59
+ puts "x = (1-t)^3 #{p[0]} + 3(1-t)^2 t#{p[2]} + 3(1-t)t^2 #{p[4]} + t^3 #{p[6]}"
60
+ puts "y = -1 * ((1-t)^3 #{p[1]} + 3(1-t)^2 t#{p[3]} + 3(1-t)t^2 #{p[5]} + t^3 #{p[7]})"
61
+ puts ""
62
+ end
63
+
64
+ end
65
+
66
+
67
+ class Bezier < Processing::App
68
+
69
+ attr_accessor :curves, :c1x, :c1y, :c2x, :c2y
70
+
71
+ X1, Y1, X2, Y2 = 50.0, 50.0, 250.0, 250.0
72
+ REDDISH = [250, 100, 100]
73
+ RADIUS = 7
74
+
75
+ load_library :control_panel
76
+
77
+ def setup
78
+ smooth
79
+ @curves = []
80
+
81
+ control_panel do |c|
82
+ c.button :new_curve
83
+ c.button :print_equations
84
+ end
85
+
86
+ generate_curve
87
+ end
88
+
89
+
90
+ def print_equations
91
+ @curves.each {|c| c.print_equation }
92
+ end
93
+
94
+
95
+ def control_points
96
+ return c1x, c1y, c2x, c2y
97
+ end
98
+
99
+
100
+ def set_control_points(*points)
101
+ @c1x, @c1y, @c2x, @c2y = points.any? ? points : [X1, Y1, X2, Y2]
102
+ end
103
+
104
+
105
+ def generate_curve
106
+ @curves << @current_curve = Curve.new
107
+ @current = @curves.length - 1
108
+ set_control_points(*current_curve.control_points)
109
+ end
110
+
111
+
112
+ def current_curve
113
+ @curves[@current]
114
+ end
115
+
116
+
117
+ def new_curve
118
+ current_curve.set_control_points(c1x, c1y, c2x, c2y)
119
+ generate_curve
120
+ end
121
+
122
+
123
+ def clicked_control_point?
124
+ x, y = mouse_x, mouse_y
125
+ return :one if Math.overlaps(@c1x, @c1y, x, y)
126
+ return :two if Math.overlaps(@c2x, @c2y, x, y)
127
+ end
128
+
129
+
130
+ def key_pressed
131
+ case keyCode
132
+ when 8 # Delete the current line
133
+ return if @curves.length <= 1
134
+ @curves.delete(current_curve)
135
+ @current = @curves.length - 1
136
+ when LEFT # Flip forward
137
+ @current = (@current + 1) % @curves.length
138
+ when RIGHT # Flip back
139
+ @current = (@current - 1) % @curves.length
140
+ end
141
+ set_control_points(*current_curve.control_points)
142
+ end
143
+
144
+
145
+ def mouse_pressed
146
+ switch_curve_if_endpoint_clicked
147
+ @control = clicked_control_point?
148
+ return if @control
149
+ curve = @curves.detect {|c| c.contains(mouse_x, mouse_y) }
150
+ @end_point = curve.contains(mouse_x, mouse_y) if curve
151
+ end
152
+
153
+
154
+ def mouse_released
155
+ @control, @end_point = nil, nil
156
+ end
157
+
158
+
159
+ def mouse_dragged
160
+ offs = compute_offsets
161
+ return if offs.map {|o| o.abs }.max > 100
162
+ return move_control_point(*offs) if @control
163
+ return move_end_point(*offs) && move_control_point(*offs) if @end_point
164
+ move_current_curve(*offs)
165
+ end
166
+
167
+
168
+ def switch_curve_if_endpoint_clicked
169
+ become = @curves.detect {|c| c.contains(mouse_x, mouse_y) }
170
+ return unless become && become != current_curve
171
+ current_curve.set_control_points(*control_points)
172
+ self.set_control_points(*become.control_points)
173
+ @current = @curves.index(become)
174
+ end
175
+
176
+
177
+ def move_current_curve(x_off, y_off)
178
+ @c1x += x_off; @c2x += x_off
179
+ @c1y += y_off; @c2y += y_off
180
+ current_curve.set_control_points(*control_points)
181
+ current_curve.x1 += x_off; current_curve.x2 += x_off
182
+ current_curve.y1 += y_off; current_curve.y2 += y_off
183
+ end
184
+
185
+
186
+ def move_control_point(x_off, y_off)
187
+ case @control || @end_point
188
+ when :one : @c1x += x_off and @c1y += y_off
189
+ when :two : @c2x += x_off and @c2y += y_off
190
+ end
191
+ current_curve.set_control_points(*control_points)
192
+ end
193
+
194
+
195
+ def move_end_point(x_off, y_off)
196
+ c = current_curve
197
+ case @end_point
198
+ when :one : c.x1 += x_off and c.y1 += y_off
199
+ when :two : c.x2 += x_off and c.y2 += y_off
200
+ end
201
+ end
202
+
203
+
204
+ def compute_offsets
205
+ return mouse_x - pmouse_x, mouse_y - pmouse_y
206
+ end
207
+
208
+
209
+ def draw_curves
210
+ stroke 255
211
+ no_fill
212
+ stroke_width 2
213
+ @curves.each {|curve| curve.draw }
214
+ end
215
+
216
+
217
+ def draw_current_control_points
218
+ fill *REDDISH
219
+ no_stroke
220
+ oval @c1x, @c1y, 5, 5
221
+ oval @c2x, @c2y, 5, 5
222
+ end
223
+
224
+
225
+ def draw_control_tangent_lines
226
+ c = current_curve
227
+ stroke *REDDISH
228
+ stroke_width 1
229
+ line @c1x, @c1y, c.x1, c.y1
230
+ line @c2x, @c2y, c.x2, c.y2
231
+ end
232
+
233
+
234
+ def draw
235
+ background 50
236
+ draw_control_tangent_lines
237
+ draw_curves
238
+ draw_current_control_points
239
+ end
240
+
241
+ end
242
+
243
+ Bezier.new :title => "Bezier", :width => 700, :height => 700