# Class: Motel::MovementStrategies::Elliptical

Inherits:
Motel::MovementStrategy
show all
Defined in:
lib/motel/movement_strategies/elliptical.rb

## Overview

The Elliptical MovementStrategy moves a location on an elliptical path described by major/minor axis direction vectors, and an eccentricity / semi_latus_rectum.

The path equation also depends on the value of the relative_to field indicating if the parent location is the center or a foci of the ellipse. Lastly a speed value is required indicating the angular velocity of the location.

To be valid you must specify eccentricity, semi_latus_rectum, and speed at a minimum

## Constant Summary collapse

CENTER =

Indicates that parent location is at center of elliptical path

`"center"`
FOCI =

Indicates that parent location is at one of the focis of the elliptical path

`"foci"`

## Instance Attribute Summary collapse

• Direction vector corresponding to the major axis of the elliptical path.

• Direction vector corresponding to the major axis of the elliptical path.

• Direction vector corresponding to the major axis of the elliptical path.

• Direction vector corresponding to the minor axis of the elliptical path.

• Direction vector corresponding to the minor axis of the elliptical path.

• Direction vector corresponding to the minor axis of the elliptical path.

• #e ⇒ Object (also: #eccentricity)

Describes the elliptical path through which the location moves.

• #p ⇒ Object (also: #semi_latus_rectum)

Describes the elliptical path through which the location moves.

• CENTER, FOCI

value indicates if the parent of the location tracked by this strategy is at the center or the foci of the ellipse.

• Distance the location moves per second.

#step_delay

## Class Method Summary collapse

• Generate and return a random elliptical movement strategy.

## Instance Method Summary collapse

• Combined direction vector.

• Combined major direction vector.

• Combined minor direction vector.

• constructor

Motel::MovementStrategies::Elliptical initializer.

• #location_valid?(location) ⇒ Boolean (also: #intersects?)

Return boolean indicating if the given location is on the ellipse or not TODO replace w/ intersects (below) ?.

• Implementation of Motel::MovementStrategy#move.

• Convert movement strategy to json representation and return it.

• Convert movement strategy to human readable string and return it.

• Return boolean indicating if this movement strategy is valid.

## Constructor Details

### #initialize(args = {}) ⇒ Elliptical

Motel::MovementStrategies::Elliptical initializer

Direction vectors will be normalized if not already

Parameters:

• args (Hash) (defaults to: {})

hash of options to initialize the elliptical movement strategy with

Options Hash (args):

• :direction (Array<Float>)

array containing x,y,z coords of major and minor direction vectors

• :dmajx (Float)

x coordinate of major direction vector

• :dmajy (Float)

y coordinate of major direction vector

• :dmajz (Float)

z coordinate of major direction vector

• :dminx (Float)

x coordinate of minor direction vector

• :dminy (Float)

y coordinate of minor direction vector

• :dminz (Float)

z coordinate of minor direction vector

• :speed (Float)

speed to assign to movement strategy

• :relative_to (CENTER, FOCI)

how the parent location is related to this elliptical path

• :e (Float)

eccentricity to assign to elliptical path

• :p (Float)

semi latus rectum to assign to elliptical path

Raises:

• if movement strategy is not valid (see #valid?)

 ``` 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112``` ```# File 'lib/motel/movement_strategies/elliptical.rb', line 93 def initialize(args = {}) @dmajx, @dmajy, @dmajz, @dminx, @dminy, @dminz = (args[:direction] || args['direction'] || [1,0,0,0,1,0]).flatten dmaj = args[:dmaj] || args['dmaj'] || [@dmajx,@dmajy,@dmajz] dmin = args[:dmin] || args['dmin'] || [@dminx,@dminy,@dminz] @dmajx, @dmajy, @dmajz = dmaj @dminx, @dminy, @dminz = dmin attr_from_args args, :relative_to => CENTER, :speed => nil, :e => nil, :p => nil, :dmajx => @dmajx, :dmajy => @dmajy, :dmajz => @dmajz, :dminx => @dminx, :dminy => @dminy, :dminz => @dminz super(args) @dmajx, @dmajy, @dmajz = Motel::normalize(@dmajx, @dmajy, @dmajz) @dminx, @dminy, @dminz = Motel::normalize(@dminx, @dminy, @dminz) end```

## Instance Attribute Details

### #dmajx ⇒ Object

Direction vector corresponding to the major axis of the elliptical path

 ``` 56 57 58``` ```# File 'lib/motel/movement_strategies/elliptical.rb', line 56 def dmajx @dmajx end```

### #dmajy ⇒ Object

Direction vector corresponding to the major axis of the elliptical path

 ``` 56 57 58``` ```# File 'lib/motel/movement_strategies/elliptical.rb', line 56 def dmajy @dmajy end```

### #dmajz ⇒ Object

Direction vector corresponding to the major axis of the elliptical path

 ``` 56 57 58``` ```# File 'lib/motel/movement_strategies/elliptical.rb', line 56 def dmajz @dmajz end```

### #dminx ⇒ Object

Direction vector corresponding to the minor axis of the elliptical path

 ``` 64 65 66``` ```# File 'lib/motel/movement_strategies/elliptical.rb', line 64 def dminx @dminx end```

### #dminy ⇒ Object

Direction vector corresponding to the minor axis of the elliptical path

 ``` 64 65 66``` ```# File 'lib/motel/movement_strategies/elliptical.rb', line 64 def dminy @dminy end```

### #dminz ⇒ Object

Direction vector corresponding to the minor axis of the elliptical path

 ``` 64 65 66``` ```# File 'lib/motel/movement_strategies/elliptical.rb', line 64 def dminz @dminz end```

### #e ⇒ ObjectAlso known as: eccentricity

Describes the elliptical path through which the location moves

 ``` 49 50 51``` ```# File 'lib/motel/movement_strategies/elliptical.rb', line 49 def e @e end```

### #p ⇒ ObjectAlso known as: semi_latus_rectum

Describes the elliptical path through which the location moves

 ``` 49 50 51``` ```# File 'lib/motel/movement_strategies/elliptical.rb', line 49 def p @p end```

### #relative_to ⇒ Object

CENTER, FOCI

value indicates if the parent

``````of the location tracked by this strategy is at the center or the foci
of the ellipse.
``````

Affects how elliptical path is calculated

 ``` 43 44 45``` ```# File 'lib/motel/movement_strategies/elliptical.rb', line 43 def relative_to @relative_to end```

### #speed ⇒ Object

Distance the location moves per second

 ``` 46 47 48``` ```# File 'lib/motel/movement_strategies/elliptical.rb', line 46 def speed @speed end```

## Class Method Details

### .random(args = {}) ⇒ Object

Generate and return a random elliptical movement strategy

 ``` 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377``` ```# File 'lib/motel/movement_strategies/elliptical.rb', line 351 def self.random(args = {}) dimensions = args[:dimensions] || 3 relative_to = args[:relative_to] || CENTER min_e = min_p = min_s = 0 min_e = args[:min_e] if args.has_key?(:min_e) min_p = args[:min_p] if args.has_key?(:min_p) min_s = args[:min_s] if args.has_key?(:min_s) max_e = max_p = max_s = nil max_e = args[:max_e] if args.has_key?(:max_e) max_p = args[:max_p] if args.has_key?(:max_p) max_s = args[:max_s] if args.has_key?(:max_s) eccentricity = min_e + (max_e.nil? ? rand : rand((max_e - min_e)*10000)/10000) speed = min_s + (max_s.nil? ? rand : rand((max_s - min_s)*10000)/10000) semi_latus_rectum = min_p + (max_p.nil? ? rand : rand((max_p - min_p))) direction = args[:direction] || Motel::random_axis(:dimensions => dimensions) dmajx, dmajy, dmajz = *direction[0] dminx, dminy, dminz = *direction[1] Elliptical.new :relative_to => relative_to, :speed => speed, :e => eccentricity, :p => semi_latus_rectum, :dmajx => dmajx, :dmajy => dmajy, :dmajz => dmajz, :dminx => dminx, :dminy => dminy, :dminz => dminz end```

## Instance Method Details

### #direction ⇒ Object

Combined direction vector

 ``` 72 73 74``` ```# File 'lib/motel/movement_strategies/elliptical.rb', line 72 def direction dmaj + dmin end```

### #dmaj ⇒ Object

Combined major direction vector

 ``` 59 60 61``` ```# File 'lib/motel/movement_strategies/elliptical.rb', line 59 def dmaj [@dmajx, @dmajy, @dmajz] end```

### #dmin ⇒ Object

Combined minor direction vector

 ``` 67 68 69``` ```# File 'lib/motel/movement_strategies/elliptical.rb', line 67 def dmin [@dminx, @dminy, @dminz] end```

### #location_valid?(location) ⇒ BooleanAlso known as: intersects?

Return boolean indicating if the given location is on the ellipse or not TODO replace w/ intersects (below) ?

Returns:

• (Boolean)
 ``` 331 332 333 334 335 336 337 338``` ```# File 'lib/motel/movement_strategies/elliptical.rb', line 331 def location_valid?(location) x,y,z = closest_coordinates(location) return false if x.nil? || y.nil? || z.nil? return (x - location.x).round_to(4) == 0 && (y - location.y).round_to(4) == 0 && (z - location.z).round_to(4) == 0 end```

### #move(loc, elapsed_seconds) ⇒ Object

Implementation of Motel::MovementStrategy#move

 ``` 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161``` ```# File 'lib/motel/movement_strategies/elliptical.rb', line 137 def move(loc, elapsed_seconds) # make sure this movement strategy is valid unless valid? ::RJR::Logger.warn "elliptical movement strategy not valid, not proceeding with move" return end # make sure location is on ellipse unless location_valid? loc cx,cy,cz = closest_coordinates loc ::RJR::Logger.warn "location #{loc} not on ellipse, adjusting to closest location #{cx},#{cy},#{cz} before moving" # FIXME raise error if cx,cy,cz is nil loc.x,loc.y,loc.z = cx,cy,cz end ::RJR::Logger.debug "moving location #{loc.id} via elliptical movement strategy" # calculate distance moved and update x,y,z accordingly distance = speed * elapsed_seconds nX,nY,nZ = coordinates_from_theta(theta(loc) + distance) loc.x = nX loc.y = nY loc.z = nZ end```

### #random_coordinates ⇒ Object

 ``` 341 342 343``` ```# File 'lib/motel/movement_strategies/elliptical.rb', line 341 def random_coordinates coordinates_from_theta(Math.random * 2 * Math::PI) end```

### #to_json(*a) ⇒ Object

Convert movement strategy to json representation and return it

 ``` 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178``` ```# File 'lib/motel/movement_strategies/elliptical.rb', line 164 def to_json(*a) { 'json_class' => self.class.name, 'data' => { :step_delay => step_delay, :speed => speed, :relative_to => relative_to, :e => e, :p => p, :dmajx => dmajx, :dmajy => dmajy, :dmajz => dmajz, :dminx => dminx, :dminy => dminy, :dminz => dminz } }.to_json(*a) end```

### #to_s ⇒ Object

Convert movement strategy to human readable string and return it

 ``` 181 182 183``` ```# File 'lib/motel/movement_strategies/elliptical.rb', line 181 def to_s "elliptical-(rt_#{relative_to}/s#{speed}/e#{e}/p#{p}/d#{direction})" end```

### #valid? ⇒ Boolean

Return boolean indicating if this movement strategy is valid

Tests the various attributes of the elliptical movement strategy, returning 'true' if everything is consistent, else false.

Currently tests

• direction vectors are normalized

• direction vectors are orthogonal

• eccentricity is a valid numeric > 0

• semi latus rectum is a valid numeric > 0

• speed is a valid numeric > 0

• relative_to is CENTER or FOCI

Returns:

• (Boolean)
 ``` 126 127 128 129 130 131 132 133 134``` ```# File 'lib/motel/movement_strategies/elliptical.rb', line 126 def valid? Motel::normalized?(@dmajx, @dmajy, @dmajz) && Motel::normalized?(@dminx, @dminy, @dminz) && Motel::orthogonal?(@dmajx, @dmajy, @dmajz, @dminx, @dminy, @dminz) && @e.numeric? && @e >= 0 && @e <= 1 && @p.numeric? && @p > 0 && @speed.numeric? && @speed > 0 && [CENTER, FOCI].include?(@relative_to) end```