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.
- data/CHANGELOG +12 -0
- data/lib/ruby-processing.rb +2 -1
- data/lib/ruby-processing/app.rb +7 -5
- data/lib/ruby-processing/exporters/creator.rb +7 -4
- data/lib/ruby-processing/helpers/numeric.rb +11 -0
- data/lib/ruby-processing/helpers/string.rb +8 -0
- data/lib/ruby-processing/runner.rb +11 -10
- data/lib/ruby-processing/runners/watch.rb +33 -0
- data/samples/bezier_playground.rb +243 -0
- data/samples/flight_patterns.rb +1 -1
- data/samples/learning_processing/chapter_16/01_display_video.rb +1 -1
- data/samples/learning_processing/chapter_16/02_manipulate_video_image.rb +1 -1
- data/samples/processing_app/basics/arrays/array.rb +41 -0
- data/samples/processing_app/basics/arrays/array_2d.rb +38 -0
- data/samples/processing_app/basics/arrays/array_objects.rb +67 -0
- data/samples/processing_app/basics/color/brightness.rb +30 -0
- data/samples/processing_app/basics/color/color_wheel.rb +97 -0
- data/samples/processing_app/basics/color/creating.rb +37 -0
- data/samples/processing_app/basics/color/hue.rb +29 -0
- data/samples/processing_app/basics/color/linear_gradient.rb +47 -0
- data/samples/processing_app/basics/color/radial_gradient.rb +52 -0
- data/samples/processing_app/basics/color/reading/data/cait.jpg +0 -0
- data/samples/processing_app/basics/color/reading/reading.rb +43 -0
- data/samples/processing_app/basics/color/relativity.rb +38 -0
- data/samples/processing_app/basics/color/saturation.rb +35 -0
- data/samples/processing_app/basics/color/wave_gradient.rb +45 -0
- data/samples/processing_app/basics/control/conditionals1.rb +51 -0
- data/samples/processing_app/basics/control/conditionals2.rb +44 -0
- data/samples/processing_app/basics/control/embedded_iteration.rb +42 -0
- data/samples/processing_app/basics/control/iteration.rb +61 -0
- data/samples/processing_app/basics/control/logical_operators.rb +59 -0
- data/samples/processing_app/basics/data/characters_strings/characters_strings.rb +87 -0
- data/samples/processing_app/basics/data/characters_strings/data/Eureka-90.vlw +0 -0
- data/samples/processing_app/basics/data/characters_strings/data/rathausFrog.jpg +0 -0
- data/samples/processing_app/basics/data/datatype_conversion.rb +45 -0
- data/samples/processing_app/basics/data/integers_floats.rb +34 -0
- data/samples/processing_app/basics/data/true_false.rb +37 -0
- data/samples/processing_app/basics/data/variable_scope.rb +80 -0
- data/samples/processing_app/basics/data/variables.rb +40 -0
- data/samples/processing_app/basics/form/bezier.rb +23 -0
- data/samples/processing_app/basics/form/bezier_ellipse.rb +110 -0
- data/samples/processing_app/basics/form/pie_chart.rb +31 -0
- data/samples/processing_app/basics/form/points_lines.rb +37 -0
- data/samples/processing_app/basics/form/shape_primitives.rb +25 -0
- data/samples/processing_app/basics/form/triangle_strip.rb +43 -0
- data/samples/processing_app/basics/form/vertices.rb +51 -0
- data/samples/processing_app/basics/image/alphamask.rb +23 -0
- data/samples/processing_app/basics/image/background_image.rb +30 -0
- data/samples/processing_app/basics/image/create_image.rb +23 -0
- data/samples/processing_app/basics/image/data/construct.jpg +0 -0
- data/samples/processing_app/basics/image/data/eames.jpg +0 -0
- data/samples/processing_app/basics/image/data/jelly.jpg +0 -0
- data/samples/processing_app/basics/image/data/mask.jpg +0 -0
- data/samples/processing_app/basics/image/data/milan_rubbish.jpg +0 -0
- data/samples/processing_app/basics/image/data/teddy.gif +0 -0
- data/samples/processing_app/basics/image/data/test.jpg +0 -0
- data/samples/processing_app/basics/image/data/wash.jpg +0 -0
- data/samples/processing_app/basics/image/load_display_image.rb +25 -0
- data/samples/processing_app/basics/image/pointillism.rb +30 -0
- data/samples/processing_app/basics/image/request_image.rb +71 -0
- data/samples/processing_app/basics/image/sprite.rb +38 -0
- data/samples/processing_app/basics/image/transparency.rb +27 -0
- data/samples/processing_app/basics/input/clock.rb +46 -0
- data/samples/processing_app/basics/input/constrain.rb +39 -0
- data/samples/processing_app/basics/input/easing.rb +33 -0
- data/samples/processing_app/basics/input/keyboard.rb +36 -0
- data/samples/processing_app/basics/input/keyboard_2.rb +45 -0
- data/samples/processing_app/basics/input/keyboard_functions.rb +87 -0
- data/samples/processing_app/basics/input/milliseconds.rb +25 -0
- data/samples/processing_app/basics/input/mouse_1d.rb +34 -0
- data/samples/processing_app/basics/input/mouse_2d.rb +25 -0
- data/samples/processing_app/basics/input/mouse_functions.rb +73 -0
- data/samples/processing_app/basics/input/mouse_press.rb +21 -0
- data/samples/processing_app/basics/input/mouse_signals.rb +45 -0
- data/samples/processing_app/basics/input/storing_input.rb +39 -0
- data/samples/processing_app/basics/math/additive_wave.rb +66 -0
- data/samples/processing_app/basics/math/arctangent.rb +54 -0
- data/samples/processing_app/topics/simulate/chain.rb +82 -0
- data/samples/processing_app/topics/simulate/multiple_particle_systems.rb +166 -0
- data/samples/processing_app/topics/simulate/simple_particle_system.rb +113 -0
- data/samples/processing_app/topics/simulate/spring.rb +85 -0
- data/samples/processing_app/topics/simulate/springs.rb +125 -0
- metadata +93 -2
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'ruby-processing'
|
2
|
+
|
3
|
+
# Move the mouse across the screen to change the position
|
4
|
+
# of the circles. The positions of the mouse are recorded
|
5
|
+
# into an array and played back every frame. Between each
|
6
|
+
# frame, the newest value are added to the end of each array
|
7
|
+
# and the oldest value is deleted.
|
8
|
+
|
9
|
+
class StoringInput < Processing::App
|
10
|
+
|
11
|
+
def setup
|
12
|
+
@num = 60
|
13
|
+
@mx = Array.new @num, 0
|
14
|
+
@my = Array.new @num, 0
|
15
|
+
|
16
|
+
smooth
|
17
|
+
no_stroke
|
18
|
+
fill 255, 153
|
19
|
+
end
|
20
|
+
|
21
|
+
def draw
|
22
|
+
background 51
|
23
|
+
|
24
|
+
(1...@num).each do |i|
|
25
|
+
@mx[i-1] = @mx[i]
|
26
|
+
@my[i-1] = @my[i]
|
27
|
+
end
|
28
|
+
|
29
|
+
@mx[@num-1] = mouse_x
|
30
|
+
@my[@num-1] = mouse_y
|
31
|
+
|
32
|
+
(0...@num).each do |i|
|
33
|
+
ellipse @mx[i], @my[i], i/2, i/2
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
StoringInput.new :title => "Storing Input", :width => 200, :height => 200
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'ruby-processing'
|
2
|
+
|
3
|
+
# Additive Wave
|
4
|
+
# by Daniel Shiffman.
|
5
|
+
#
|
6
|
+
# Create a more complex wave by adding two waves together.
|
7
|
+
|
8
|
+
class AdditiveWave < Processing::App
|
9
|
+
|
10
|
+
def setup
|
11
|
+
@max_waves = 4 # Total number of waves to add together
|
12
|
+
@wave_width = width + 16 # Width of entire wave
|
13
|
+
@x_spacing = 8 # How far apart should each horizontal location be spaced
|
14
|
+
@theta = 0.0
|
15
|
+
@amplitude = [] # Height of wave
|
16
|
+
@dx = [] # Value for incrementing X, to be calculated as a function of period and x_spacing
|
17
|
+
|
18
|
+
@max_waves.times do |i|
|
19
|
+
@amplitude << random( 10, 30 )
|
20
|
+
period = random( 100, 300 ) # How many pixels before the wave repeats
|
21
|
+
@dx << (TWO_PI / period) * @x_spacing
|
22
|
+
end
|
23
|
+
|
24
|
+
frame_rate 30
|
25
|
+
color_mode RGB, 255, 255, 255, 100
|
26
|
+
smooth
|
27
|
+
end
|
28
|
+
|
29
|
+
def draw
|
30
|
+
background 0
|
31
|
+
calculate_wave
|
32
|
+
render_wave
|
33
|
+
end
|
34
|
+
|
35
|
+
def calculate_wave
|
36
|
+
# Increment theta (try different values for 'angular velocity' here
|
37
|
+
@theta += 0.02
|
38
|
+
|
39
|
+
# Set all height values to zero
|
40
|
+
@y_values = Array.new @wave_width/@x_spacing, 0
|
41
|
+
|
42
|
+
# Accumulate wave height values
|
43
|
+
@max_waves.times do |j|
|
44
|
+
x = @theta
|
45
|
+
@y_values.length.times do |i|
|
46
|
+
# Every other wave is cosine instead of sine
|
47
|
+
value = (j % 2) == 0 ? sin(x) : cos(x)
|
48
|
+
@y_values[i] += value * @amplitude[j]
|
49
|
+
x += @dx[j]
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def render_wave
|
55
|
+
# A simple way to draw the wave with an ellipse at each location
|
56
|
+
no_stroke
|
57
|
+
fill 255, 50
|
58
|
+
ellipse_mode CENTER
|
59
|
+
@y_values.each_with_index do |y, i|
|
60
|
+
ellipse i*@x_spacing, width/2+y, 16, 16
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
AdditiveWave.new :title => "Additive Wave", :width => 200, :height => 200
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'ruby-processing'
|
2
|
+
|
3
|
+
# Move the mouse to change the direction of the eyes.
|
4
|
+
# The atan2() function computes the angle from each eye
|
5
|
+
# to the cursor.
|
6
|
+
|
7
|
+
class Arctangent < Processing::App
|
8
|
+
|
9
|
+
def setup
|
10
|
+
@eyes = [
|
11
|
+
Eye.new( 50, 16, 80),
|
12
|
+
Eye.new( 64, 85, 40),
|
13
|
+
Eye.new( 90, 200, 120),
|
14
|
+
Eye.new( 150, 44, 40),
|
15
|
+
Eye.new( 175, 120, 80)
|
16
|
+
]
|
17
|
+
|
18
|
+
smooth
|
19
|
+
no_stroke
|
20
|
+
end
|
21
|
+
|
22
|
+
def draw
|
23
|
+
background 102
|
24
|
+
|
25
|
+
@eyes.each do |eye|
|
26
|
+
eye.update mouse_x, mouse_y
|
27
|
+
eye.display self
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class Eye
|
32
|
+
def initialize( _x, _y, _s) # contructor, called by Eye.new
|
33
|
+
@x, @y, @size = _x, _y, _s
|
34
|
+
end
|
35
|
+
|
36
|
+
def update( mx, my )
|
37
|
+
@angle = Arctangent::atan2( my-@y, mx-@x )
|
38
|
+
end
|
39
|
+
|
40
|
+
def display( context )
|
41
|
+
context.push_matrix
|
42
|
+
context.translate @x, @y
|
43
|
+
context.fill 255
|
44
|
+
context.ellipse 0, 0, @size, @size
|
45
|
+
context.rotate @angle
|
46
|
+
context.fill 153
|
47
|
+
context.ellipse @size/4, 0, @size/2, @size/2
|
48
|
+
context.pop_matrix
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
Arctangent.new :title => "Arctangent", :width => 200, :height => 200
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'ruby-processing'
|
2
|
+
|
3
|
+
#
|
4
|
+
# Ported from http://processing.org/learning/topics/chain.html
|
5
|
+
#
|
6
|
+
# One mass is attached to the mouse position and the other is attached the position of the other mass.
|
7
|
+
# The gravity in the environment pulls down on both.
|
8
|
+
#
|
9
|
+
class Chain < Processing::App
|
10
|
+
|
11
|
+
attr_reader :gravity
|
12
|
+
|
13
|
+
load_library :control_panel
|
14
|
+
|
15
|
+
def setup
|
16
|
+
smooth
|
17
|
+
fill 0
|
18
|
+
|
19
|
+
# Inputs: spring1, spring2, mass, gravity
|
20
|
+
@gravity = 6.0
|
21
|
+
@mass = 2.0
|
22
|
+
@s1 = Spring2d.new(width/2, height/2, @mass)
|
23
|
+
@s2 = Spring2d.new(width/2, height/2, @mass)
|
24
|
+
|
25
|
+
# Control panel for changing gravity
|
26
|
+
control_panel do |c|
|
27
|
+
c.slider :gravity, 0..30
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def draw
|
32
|
+
background 204
|
33
|
+
@s1.update(mouse_x, mouse_y)
|
34
|
+
display(@s1, mouse_x, mouse_y)
|
35
|
+
|
36
|
+
@s2.update(@s1.x, @s1.y)
|
37
|
+
display(@s2, @s1.x, @s1.y)
|
38
|
+
end
|
39
|
+
|
40
|
+
def display(spring, nx, ny)
|
41
|
+
no_stroke
|
42
|
+
ellipse(spring.x, spring.y, spring.diameter, spring.diameter)
|
43
|
+
stroke 255
|
44
|
+
line(spring.x, spring.y, nx, ny)
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
class Spring2d
|
50
|
+
|
51
|
+
attr_reader :x, :y
|
52
|
+
|
53
|
+
def initialize(xpos, ypos, mass)
|
54
|
+
@x = xpos # The x-coordinate
|
55
|
+
@y = ypos # The y-coordinate
|
56
|
+
@mass = mass
|
57
|
+
@vx, @vy = 0, 0 # The x- and y-axis velocities
|
58
|
+
@radius = 20
|
59
|
+
@stiffness = 0.2
|
60
|
+
@damping = 0.7
|
61
|
+
end
|
62
|
+
|
63
|
+
def update(target_x, target_y)
|
64
|
+
force_x = (target_x - self.x) * @stiffness
|
65
|
+
ax = force_x / @mass
|
66
|
+
@vx = @damping * (@vx + ax)
|
67
|
+
@x += @vx
|
68
|
+
|
69
|
+
force_y = (target_y - self.y) * @stiffness
|
70
|
+
force_y += $app.gravity
|
71
|
+
ay = force_y / @mass
|
72
|
+
@vy = @damping * (@vy + ay)
|
73
|
+
@y += @vy
|
74
|
+
end
|
75
|
+
|
76
|
+
def diameter
|
77
|
+
@radius * 2
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
|
82
|
+
Chain.new(:width => 200, :height => 200, :title => "Chain", :full_screen => false)
|
@@ -0,0 +1,166 @@
|
|
1
|
+
# Ported from http://processing.org/learning/topics/multipleparticlesystems.html
|
2
|
+
|
3
|
+
# Click the mouse to generate a burst of particles at mouse location.
|
4
|
+
|
5
|
+
# Each burst is one instance of a particle system with Particles and
|
6
|
+
# CrazyParticles (a subclass of Particle).
|
7
|
+
|
8
|
+
|
9
|
+
require 'ruby-processing'
|
10
|
+
|
11
|
+
class MultipleParticleSystems < Processing::App
|
12
|
+
def setup
|
13
|
+
smooth
|
14
|
+
color_mode(RGB, 255, 255, 255, 100)
|
15
|
+
ellipse_mode(CENTER)
|
16
|
+
|
17
|
+
@particle_systems = []
|
18
|
+
@particle_systems.extend Runnable
|
19
|
+
end
|
20
|
+
|
21
|
+
def draw
|
22
|
+
background 0
|
23
|
+
@particle_systems.run
|
24
|
+
end
|
25
|
+
|
26
|
+
def mouse_pressed
|
27
|
+
@particle_systems << ParticleSystem.new(rand(21) + 5, Vector.new(mouse_x, mouse_y))
|
28
|
+
end
|
29
|
+
|
30
|
+
module Runnable
|
31
|
+
def run
|
32
|
+
self.reject! { |item| item.dead? }
|
33
|
+
self.each { |item| item.run }
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
class ParticleSystem < Array
|
38
|
+
include Runnable
|
39
|
+
alias_method :dead?, :empty?
|
40
|
+
|
41
|
+
def initialize(number, origin)
|
42
|
+
super()
|
43
|
+
@origin = origin
|
44
|
+
kind = rand < 0.5 ? Particle : CrazyParticle
|
45
|
+
number.times { self << kind.new(origin) }
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
class Particle
|
50
|
+
def initialize(origin)
|
51
|
+
@origin = origin
|
52
|
+
@velocity = Vector.new(rand * 2 - 1, rand * 2 - 2)
|
53
|
+
@acceleration = Vector.new(0, 0.05)
|
54
|
+
@radius = 10
|
55
|
+
@lifespan = 100
|
56
|
+
end
|
57
|
+
|
58
|
+
def run
|
59
|
+
update
|
60
|
+
grow
|
61
|
+
render
|
62
|
+
render_velocity_vector
|
63
|
+
end
|
64
|
+
|
65
|
+
def update
|
66
|
+
@velocity += @acceleration
|
67
|
+
@origin += @velocity
|
68
|
+
end
|
69
|
+
|
70
|
+
def grow
|
71
|
+
@lifespan -= 1
|
72
|
+
end
|
73
|
+
|
74
|
+
def dead?
|
75
|
+
@lifespan <= 0
|
76
|
+
end
|
77
|
+
|
78
|
+
def render
|
79
|
+
$app.stroke(255, @lifespan)
|
80
|
+
$app.fill(100, @lifespan)
|
81
|
+
$app.ellipse(@origin.x, @origin.y, @radius, @radius)
|
82
|
+
end
|
83
|
+
|
84
|
+
def render_velocity_vector
|
85
|
+
scale = 10
|
86
|
+
arrow_size = 4
|
87
|
+
|
88
|
+
$app.push_matrix
|
89
|
+
|
90
|
+
$app.translate(@origin.x, @origin.y)
|
91
|
+
$app.rotate(@velocity.heading)
|
92
|
+
|
93
|
+
length = @velocity.magnitude * scale
|
94
|
+
|
95
|
+
$app.line 0, 0, length, 0
|
96
|
+
$app.line length, 0, length - arrow_size, arrow_size / 2
|
97
|
+
$app.line length, 0, length - arrow_size, -arrow_size / 2
|
98
|
+
|
99
|
+
$app.pop_matrix
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
class CrazyParticle < Particle
|
104
|
+
def initialize(origin)
|
105
|
+
super
|
106
|
+
@theta = 0
|
107
|
+
end
|
108
|
+
|
109
|
+
def run
|
110
|
+
update
|
111
|
+
grow
|
112
|
+
render
|
113
|
+
render_rotation_line
|
114
|
+
end
|
115
|
+
|
116
|
+
def update
|
117
|
+
super
|
118
|
+
@theta += @velocity.x * @velocity.magnitude / 10
|
119
|
+
end
|
120
|
+
|
121
|
+
def grow
|
122
|
+
@lifespan -= 0.8
|
123
|
+
end
|
124
|
+
|
125
|
+
def render_rotation_line
|
126
|
+
$app.push_matrix
|
127
|
+
|
128
|
+
$app.translate(@origin.x, @origin.y)
|
129
|
+
$app.rotate(@theta)
|
130
|
+
|
131
|
+
$app.stroke(255, @lifespan)
|
132
|
+
|
133
|
+
$app.line(0, 0, 25, 0)
|
134
|
+
|
135
|
+
$app.pop_matrix
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
class Vector
|
140
|
+
attr_accessor :x, :y
|
141
|
+
|
142
|
+
def initialize(x, y)
|
143
|
+
@x, @y = x, y
|
144
|
+
end
|
145
|
+
|
146
|
+
def +(other)
|
147
|
+
if other.is_a?(Numeric)
|
148
|
+
Vector.new(@x + other, @y + other)
|
149
|
+
elsif other.is_a?(Vector)
|
150
|
+
Vector.new(@x + other.x, @y + other.y)
|
151
|
+
else
|
152
|
+
self
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
def heading
|
157
|
+
-1 * Math::atan2(-@y, @x)
|
158
|
+
end
|
159
|
+
|
160
|
+
def magnitude
|
161
|
+
@x * @x + @y * @y
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
$app = MultipleParticleSystems.new :width => 640, :height => 340, :title => 'MultipleParticleSystems'
|
@@ -0,0 +1,113 @@
|
|
1
|
+
# Ported from http://processing.org/learning/topics/simpleparticlesystem.html
|
2
|
+
|
3
|
+
# Particles are generated each cycle, fall with gravity and fade out over
|
4
|
+
# time. A ParticleSystem (Array) object manages a variable size list of
|
5
|
+
# particles.
|
6
|
+
|
7
|
+
require 'ruby-processing'
|
8
|
+
|
9
|
+
class SimpleParticleSystem < Processing::App
|
10
|
+
def setup
|
11
|
+
smooth
|
12
|
+
color_mode(RGB, 255, 255, 255, 100)
|
13
|
+
ellipse_mode(CENTER)
|
14
|
+
|
15
|
+
@particles = []
|
16
|
+
@particles.extend Runnable
|
17
|
+
end
|
18
|
+
|
19
|
+
def draw
|
20
|
+
background 0
|
21
|
+
@particles.run
|
22
|
+
@particles << Particle.new(Vector.new(mouse_x, mouse_y))
|
23
|
+
end
|
24
|
+
|
25
|
+
module Runnable
|
26
|
+
def run
|
27
|
+
self.reject! { |particle| particle.dead? }
|
28
|
+
self.each { |particle| particle.run }
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class Particle
|
33
|
+
def initialize(origin)
|
34
|
+
@origin = origin
|
35
|
+
@velocity = Vector.new(rand * 2 - 1, rand * 2 - 2)
|
36
|
+
@acceleration = Vector.new(0, 0.05)
|
37
|
+
@radius = 10
|
38
|
+
@lifespan = 100
|
39
|
+
end
|
40
|
+
|
41
|
+
def run
|
42
|
+
update
|
43
|
+
grow
|
44
|
+
render
|
45
|
+
render_velocity_vector
|
46
|
+
end
|
47
|
+
|
48
|
+
def update
|
49
|
+
@velocity += @acceleration
|
50
|
+
@origin += @velocity
|
51
|
+
end
|
52
|
+
|
53
|
+
def grow
|
54
|
+
@lifespan -= 1
|
55
|
+
end
|
56
|
+
|
57
|
+
def dead?
|
58
|
+
@lifespan <= 0
|
59
|
+
end
|
60
|
+
|
61
|
+
def render
|
62
|
+
$app.stroke(255, @lifespan)
|
63
|
+
$app.fill(100, @lifespan)
|
64
|
+
$app.ellipse(@origin.x, @origin.y, @radius, @radius)
|
65
|
+
end
|
66
|
+
|
67
|
+
def render_velocity_vector
|
68
|
+
scale = 10
|
69
|
+
arrow_size = 4
|
70
|
+
|
71
|
+
$app.push_matrix
|
72
|
+
|
73
|
+
$app.translate(@origin.x, @origin.y)
|
74
|
+
$app.rotate(@velocity.heading)
|
75
|
+
|
76
|
+
length = @velocity.magnitude * scale
|
77
|
+
|
78
|
+
$app.line 0, 0, length, 0
|
79
|
+
$app.line length, 0, length - arrow_size, arrow_size / 2
|
80
|
+
$app.line length, 0, length - arrow_size, -arrow_size / 2
|
81
|
+
|
82
|
+
$app.pop_matrix
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
class Vector
|
87
|
+
attr_accessor :x, :y
|
88
|
+
|
89
|
+
def initialize(x, y)
|
90
|
+
@x, @y = x, y
|
91
|
+
end
|
92
|
+
|
93
|
+
def +(other)
|
94
|
+
if other.is_a?(Numeric)
|
95
|
+
Vector.new(@x + other, @y + other)
|
96
|
+
elsif other.is_a?(Vector)
|
97
|
+
Vector.new(@x + other.x, @y + other.y)
|
98
|
+
else
|
99
|
+
self
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def heading
|
104
|
+
-1 * Math::atan2(-@y, @x)
|
105
|
+
end
|
106
|
+
|
107
|
+
def magnitude
|
108
|
+
@x * @x + @y * @y
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
$app = SimpleParticleSystem.new :width => 640, :height => 340, :title => 'SimpleParticleSystem'
|