Class: Graphics::Body
- Inherits:
-
Object
- Object
- Graphics::Body
- Defined in:
- lib/graphics/body.rb
Overview
A body in the simulation.
All bodies know their position, their angle, goal angle (optional), and momentum.
Constant Summary collapse
- D2R =
degrees to radians
Graphics::Simulation::D2R
- R2D =
radians to degrees
Graphics::Simulation::R2D
- NORMAL =
The normals for the cardinal directions.
{ :north => 270, :south => 90, :east => 180, :west => 0, }
Instance Attribute Summary collapse
-
#a ⇒ Object
Body’s angle, in degrees.
-
#ga ⇒ Object
Body’s goal angle, in degrees.
-
#m ⇒ Object
Body’s magnitude.
-
#w ⇒ Object
Body’s window.
-
#x ⇒ Object
Body’s x coordinate.
-
#y ⇒ Object
Body’s y coordinate.
Instance Method Summary collapse
-
#angle_to(body) ⇒ Object
Return the angle to another body in degrees.
-
#bounce(friction = 0.2) ⇒ Object
Like clip, keep the body in bounds of the window, but set the angle to the angle of reflection.
-
#clip ⇒ Object
Keep the body in bounds of the window.
-
#clip_off_wall ⇒ Object
clip and then set the goal angle to the normal plus or minus a random 45 degrees.
-
#distance_to_squared(p) ⇒ Object
Return the distance to another body, squared.
-
#dx_dy ⇒ Object
:nodoc:.
-
#initialize(w) ⇒ Body
constructor
Create a new body in windowing system
w
with a random x/y and everything else zero’d out. -
#inspect ⇒ Object
:nodoc:.
-
#m_a ⇒ Object
:nodoc:.
-
#move ⇒ Object
Move the body via its current angle and momentum.
-
#move_by(a, m) ⇒ Object
Move the body by a specified angle and momentum.
-
#position ⇒ Object
Convert the body to a vector representing its position.
-
#position=(o) ⇒ Object
Set the body’s position from a velocity vector.
-
#random_angle ⇒ Object
Return a random angle 0…360.
-
#random_turn(deg) ⇒ Object
Randomly turn the body inside an arc of
deg
degrees from where it is currently facing. -
#turn(dir) ⇒ Object
Turn the body
dir
degrees. -
#update ⇒ Object
Update the body.
-
#velocity ⇒ Object
Convert the body to a vector representing its velocity.
-
#velocity=(o) ⇒ Object
Set the body’s magnitude and angle from a velocity vector.
-
#wrap ⇒ Object
Wrap the body if it hits an edge.
Constructor Details
#initialize(w) ⇒ Body
Create a new body in windowing system w
with a random x/y and everything else zero’d out.
64 65 66 67 68 69 70 71 |
# File 'lib/graphics/body.rb', line 64 def initialize w self.w = w self.x, self.y = rand(w.w), rand(w.h) self.a = 0.0 self.ga = 0.0 self.m = 0.0 end |
Instance Attribute Details
#a ⇒ Object
Body’s angle, in degrees.
43 44 45 |
# File 'lib/graphics/body.rb', line 43 def a @a end |
#ga ⇒ Object
Body’s goal angle, in degrees.
48 49 50 |
# File 'lib/graphics/body.rb', line 48 def ga @ga end |
#m ⇒ Object
Body’s magnitude.
53 54 55 |
# File 'lib/graphics/body.rb', line 53 def m @m end |
#w ⇒ Object
Body’s window.
58 59 60 |
# File 'lib/graphics/body.rb', line 58 def w @w end |
#x ⇒ Object
Body’s x coordinate.
33 34 35 |
# File 'lib/graphics/body.rb', line 33 def x @x end |
#y ⇒ Object
Body’s y coordinate.
38 39 40 |
# File 'lib/graphics/body.rb', line 38 def y @y end |
Instance Method Details
#angle_to(body) ⇒ Object
Return the angle to another body in degrees.
134 135 136 137 138 139 |
# File 'lib/graphics/body.rb', line 134 def angle_to body dx = body.x - self.x dy = body.y - self.y (R2D * Math.atan2(dy, dx)).degrees end |
#bounce(friction = 0.2) ⇒ Object
Like clip, keep the body in bounds of the window, but set the angle to the angle of reflection. Also slows momentum by friction
%.
236 237 238 239 240 241 242 |
# File 'lib/graphics/body.rb', line 236 def bounce friction = 0.2 if wall = clip then self.a = (2 * NORMAL[wall] - 180 - a).degrees self.m *= (1.0 - friction) if friction and friction > 0 true end end |
#clip ⇒ Object
Keep the body in bounds of the window. If it went out of bounds, set its position to be on that bound and return the cardinal direction of the wall it hit.
See also: NORMALS
184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 |
# File 'lib/graphics/body.rb', line 184 def clip max_h, max_w = w.h, w.w if x < 0 then self.x = x.abs return :west elsif x > max_w then self.x = 2 * max_w - x return :east end if y < 0 then self.y = y.abs return :south elsif y > max_h then self.y = 2 * max_h - y return :north end nil end |
#clip_off_wall ⇒ Object
clip and then set the goal angle to the normal plus or minus a random 45 degrees.
225 226 227 228 229 230 |
# File 'lib/graphics/body.rb', line 225 def clip_off_wall if wall = clip then normal = NORMAL[wall] self.ga = (normal + random_turn(90)).degrees unless (normal - ga).abs < 45 end end |
#distance_to_squared(p) ⇒ Object
Return the distance to another body, squared.
144 145 146 147 148 |
# File 'lib/graphics/body.rb', line 144 def distance_to_squared p dx = p.x - x dy = p.y - y dx * dx + dy * dy end |
#dx_dy ⇒ Object
:nodoc:
124 125 126 127 128 129 |
# File 'lib/graphics/body.rb', line 124 def dx_dy # :nodoc: rad = a * D2R dx = Math.cos(rad) * m dy = Math.sin(rad) * m [dx, dy] end |
#inspect ⇒ Object
:nodoc:
81 82 83 84 |
# File 'lib/graphics/body.rb', line 81 def inspect # :nodoc: "%s(%.2fx%.2f @ %.2f°x%.2f == %p @ %p)" % [self.class, x, y, a, m, position, velocity] end |
#m_a ⇒ Object
:nodoc:
150 151 152 |
# File 'lib/graphics/body.rb', line 150 def m_a # :nodoc: [m, a] end |
#move ⇒ Object
Move the body via its current angle and momentum.
164 165 166 |
# File 'lib/graphics/body.rb', line 164 def move move_by a, m end |
#move_by(a, m) ⇒ Object
Move the body by a specified angle and momentum.
171 172 173 174 175 |
# File 'lib/graphics/body.rb', line 171 def move_by a, m rad = a * D2R self.x += Math.cos(rad) * m self.y += Math.sin(rad) * m end |
#position ⇒ Object
Convert the body to a vector representing its position.
DO NOT modify this vector expecting it to modify the body. It is a copy.
112 113 114 |
# File 'lib/graphics/body.rb', line 112 def position V[x, y] end |
#position=(o) ⇒ Object
Set the body’s position from a velocity vector.
119 120 121 122 |
# File 'lib/graphics/body.rb', line 119 def position= o self.x = o.x self.y = o.y end |
#random_angle ⇒ Object
Return a random angle 0…360.
209 210 211 |
# File 'lib/graphics/body.rb', line 209 def random_angle 360 * rand end |
#random_turn(deg) ⇒ Object
Randomly turn the body inside an arc of deg
degrees from where it is currently facing.
217 218 219 |
# File 'lib/graphics/body.rb', line 217 def random_turn deg rand(deg) - (deg/2) end |
#turn(dir) ⇒ Object
Turn the body dir
degrees.
157 158 159 |
# File 'lib/graphics/body.rb', line 157 def turn dir self.a = (a + dir).degrees if dir end |
#update ⇒ Object
Update the body. Does nothing by default. Override this method to add behavior to the body.
77 78 79 |
# File 'lib/graphics/body.rb', line 77 def update # do nothing end |
#velocity ⇒ Object
Convert the body to a vector representing its velocity.
DO NOT modify this vector expecting it to modify the body. It is a copy.
92 93 94 95 |
# File 'lib/graphics/body.rb', line 92 def velocity x, y = dx_dy V[x, y] end |
#velocity=(o) ⇒ Object
Set the body’s magnitude and angle from a velocity vector.
100 101 102 103 104 |
# File 'lib/graphics/body.rb', line 100 def velocity= o dx, dy = o.x, o.y self.m = Math.sqrt(dx*dx + dy*dy) self.a = Math.atan2(dy, dx) * R2D end |
#wrap ⇒ Object
Wrap the body if it hits an edge.
247 248 249 250 251 252 253 254 255 |
# File 'lib/graphics/body.rb', line 247 def wrap max_h, max_w = w.h, w.w self.x = max_w if x < 0 self.y = max_h if y < 0 self.x = 0 if x > max_w self.y = 0 if y > max_h end |