ruby-processing 1.0.2 → 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
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