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.
- 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'
|