Class: RubyLabs::SphereLab::Turtle

Inherits:
Object
  • Object
show all
Defined in:
lib/spherelab.rb

Overview

Turtle

This class implements a rudimentary “turtle graphics” system. A turtle is an object that moves around on a canvas, under direction from a user/program that tells it to advance, turn, etc. A turtle also has a “pen” that can be raised or lowered. When the pen is down, the turtle draws a line on the canvas as it moves.

A Turtle object is used in the robot explorer experiment, where the object is to get the robot to move in as smooth a circle as possible about a central point.

Constant Summary collapse

@@turtleOptions =
{
  :x => 20,
  :y => 100,
  :heading => 0,
  :speed => 10,
  :track => :off,
}
@@north =
Vector.new(0, 10, 0)

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(args = nil) ⇒ Turtle

Create a new Turtle object. The arguments (all optional) specify the turtle’s starting position and orientation. The possible options and their default values:

:x => 20
:y => 100
:heading => 0
:speed => 10
:track => :off

Example:

>> t = Turtle.new
=> #<SphereLab::Turtle x: 20 y: 100 heading: 360 speed: 10.00>
>> t = Turtle.new( :x => 100, :y => 100, :speed => 5 )
=> #<SphereLab::Turtle x: 100 y: 100 heading: 360 speed: 5.00>


318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
# File 'lib/spherelab.rb', line 318

def initialize(args = nil)
  args = { } if args.nil?
  raise "Turtle: initialize: args must be a Hash" unless args.class == Hash
  options = @@turtleOptions.merge(args)
  alpha = Canvas.radians(options[:heading] + 90.0)
  @position = Vector.new(options[:x], options[:y], 0.0)
  if options[:speed] > 0
    @velocity = Vector.new(-1.0 * options[:speed] * cos(alpha), options[:speed] * sin(alpha), 0.0)
  else
    raise "Turtle.new: speed must be greater than 0"
  end
  @graphic = nil
  @reference = nil
  @tracking = options[:track]
end

Instance Attribute Details

#graphicObject

Returns the value of attribute graphic.



293
294
295
# File 'lib/spherelab.rb', line 293

def graphic
  @graphic
end

#positionObject

Returns the value of attribute position.



293
294
295
# File 'lib/spherelab.rb', line 293

def position
  @position
end

#referenceObject

Returns the value of attribute reference.



293
294
295
# File 'lib/spherelab.rb', line 293

def reference
  @reference
end

#velocityObject

Returns the value of attribute velocity.



293
294
295
# File 'lib/spherelab.rb', line 293

def velocity
  @velocity
end

Instance Method Details

#advance(dt) ⇒ Object

Tell the turtle to move straight ahead from its current position for dt seconds.



376
377
378
379
380
381
382
383
384
# File 'lib/spherelab.rb', line 376

def advance(dt)
  prevx = @position.x
  prevy = @position.y
  @position.add( @velocity * dt )
  if @graphic
    Canvas.move(@graphic, @position.x-prevx, prevy-@position.y, @tracking)
  end
  return dt
end

#headingObject

Return the current heading, in compass degrees, of this turtle object. The heading is a number between 0 and 360, where 0 is north, 90 is east, etc.



349
350
351
352
# File 'lib/spherelab.rb', line 349

def heading
  d = Canvas.degrees( @velocity.angle(@@north) )
  return (@velocity.x < 0) ? (360 - d) : d
end

#inspectObject

Create a string that summarizes the status of this turtle object.



336
337
338
# File 'lib/spherelab.rb', line 336

def inspect
  sprintf "#<SphereLab::Turtle x: %d y: %d heading: %d speed: %.2f>", @position.x, @position.y, heading, speed 
end

#locationObject

Return an array of two numbers representing the x and y coordinates of this object.



342
343
344
# File 'lib/spherelab.rb', line 342

def location
  return [@position.x, @position.y]
end

#orientObject

Tell the turtle to rotate until its heading is orthogonal to a reference point. See the Lab Manual for details about setting a reference point and how the orientation is calculated.



390
391
392
393
394
395
396
397
398
399
400
401
402
# File 'lib/spherelab.rb', line 390

def orient
  if @reference.nil?
    puts "no reference point"
    return nil
  end
  mx, my = @reference
  tx, ty = @position.x, @position.y
  mid = Vector.new(tx-mx, ty-my, 0.0)
  theta = Canvas.degrees(mid.angle(@velocity))
  alpha = 2 * (90.0 - theta)
  turn(alpha)
  return alpha      
end

#speedObject

Return the current speed (in meters per second) of this turtle object.



356
357
358
# File 'lib/spherelab.rb', line 356

def speed
  @velocity.norm
end

#track(val) ⇒ Object

Turn tracking :on or :off. When tracking is :on the turtle draws a line on the canvas as it moves.



407
408
409
410
411
412
413
414
415
416
# File 'lib/spherelab.rb', line 407

def track(val)
  case val
  when :off  then @tracking = :off
  when :on   then @tracking = :track
  else
    puts "tracking is either :on or :off"
    return nil
  end
  return val
end

#turn(alpha) ⇒ Object

Reorient the turtle by telling it to turn clockwise by alpha degrees.



362
363
364
365
366
367
368
369
370
371
372
# File 'lib/spherelab.rb', line 362

def turn(alpha)
  theta = -1.0 * Canvas.radians(alpha)
  x = @velocity.x * cos(theta) - @velocity.y * sin(theta)
  y = @velocity.x * sin(theta) + @velocity.y * cos(theta)
  @velocity.x = x
  @velocity.y = y
  if @graphic
    @graphic.rotate(alpha)
  end
  return alpha
end