class Graphics::Body
A body in the simulation.
All bodies know their position, their angle, goal angle (optional), and momentum.
Constants
- D2R
degrees to radians
- NORMAL
The normals for the cardinal directions.
- R2D
radians to degrees
Attributes
Body’s angle, in degrees.
Body’s goal angle, in degrees.
Body’s magnitude.
Body’s window.
Body’s x coordinate.
Body’s y coordinate.
Public Class Methods
Create a new body in windowing system w
with a random x/y and everything else zero’d out.
# File lib/graphics/body.rb, line 63 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
Public Instance Methods
Return the angle to another body in degrees.
# File lib/graphics/body.rb, line 133 def angle_to body dx = body.x - self.x dy = body.y - self.y (R2D * Math.atan2(dy, dx)).degrees end
Like clip, keep the body in bounds of the window, but set the angle to the angle of reflection. Also slows momentum by friction
%.
# File lib/graphics/body.rb, line 235 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
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
# File lib/graphics/body.rb, line 183 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 and then set the goal angle to the normal plus or minus a random 45 degrees.
# File lib/graphics/body.rb, line 224 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
Return the distance to another body, squared.
# File lib/graphics/body.rb, line 143 def distance_to_squared p dx = p.x - x dy = p.y - y dx * dx + dy * dy end
Move the body via its current angle and momentum.
# File lib/graphics/body.rb, line 163 def move move_by a, m end
Move the body by a specified angle and momentum.
# File lib/graphics/body.rb, line 170 def move_by a, m rad = a * D2R self.x += Math.cos(rad) * m self.y += Math.sin(rad) * m end
Convert the body to a vector representing its position.
DO NOT modify this vector expecting it to modify the body. It is a copy.
# File lib/graphics/body.rb, line 111 def position V[x, y] end
Set the body’s position from a velocity vector.
# File lib/graphics/body.rb, line 118 def position= o self.x = o.x self.y = o.y end
Return a random angle 0…360.
# File lib/graphics/body.rb, line 208 def random_angle 360 * rand end
Randomly turn the body inside an arc of deg
degrees from where it is currently facing.
# File lib/graphics/body.rb, line 216 def random_turn deg rand(deg) - (deg/2) end
Turn the body dir
degrees.
# File lib/graphics/body.rb, line 156 def turn dir self.a = (a + dir).degrees if dir end
Update the body. Does nothing by default. Override this method to add behavior to the body.
# File lib/graphics/body.rb, line 76 def update # do nothing end
Convert the body to a vector representing its velocity.
DO NOT modify this vector expecting it to modify the body. It is a copy.
# File lib/graphics/body.rb, line 91 def velocity x, y = dx_dy V[x, y] end
Set the body’s magnitude and angle from a velocity vector.
# File lib/graphics/body.rb, line 99 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 the body if it hits an edge.
# File lib/graphics/body.rb, line 246 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