Class: Geometry::Rotation

Inherits:
Object
  • Object
show all
Includes:
ClusterFactory
Defined in:
lib/aurora-geometry/rotation.rb

Overview

A generalized representation of a rotation transformation.

Usage

Rotation.new angle:45*Math.PI/180	# Rotate 45 degrees counterclockwise
Rotation.new x:[0,1]		# Rotate 90 degrees counterclockwise

Direct Known Subclasses

RotationAngle

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from ClusterFactory

included

Constructor Details

#initialize(options = {}) ⇒ Rotation

Returns a new instance of Rotation.

Parameters:

  • options (Hash)

    a customizable set of options

[View source]

41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/aurora-geometry/rotation.rb', line 41

def initialize(*args)
    options, args = args.partition {|a| a.is_a? Hash}
    options = options.reduce({}, :merge)

    @dimensions = options[:dimensions] || nil

    axis_options = [options[:x], options[:y], options[:z]]
    all_axes_options = [options[:x], options[:y], options[:z]].select {|a| a}
    if all_axes_options.count != 0
	@x = options[:x] || nil
	@y = options[:y] || nil
	@z = options[:z] || nil

	raise ArgumentError, "All axis options must be Vectors" unless all_axes_options.all? {|a| a.is_a?(Vector) or a.is_a?(Array) }

	raise ArgumentError, "All provided axes must be the same size" unless all_axes_options.all? {|a| a.size == all_axes_options.first.size}

	@dimensions ||= all_axes_options.first.size

	raise ArgumentError, "Dimensionality mismatch" unless all_axes_options.first.size <= @dimensions
	if all_axes_options.first.size < @dimensions
	    @x, @y, @z = [@x, @y, @z].map {|a| (a && (a.size != 0) && (a.size < @dimensions)) ? Array.new(@dimensions) {|i| a[i] || 0 } : a }
	end

	raise ArgumentError, "Too many axes specified (expected #{@dimensions - 1} but got #{all_axes_options.size}" unless all_axes_options.size == (@dimensions - 1)
    end
end

Instance Attribute Details

#dimensionsInteger (readonly)

Returns dimensions.

Returns:

  • (Integer)

    dimensions


18
19
20
# File 'lib/aurora-geometry/rotation.rb', line 18

def dimensions
  @dimensions
end

#matrixMatrix (readonly)

Returns the transformation Matrix representing the Geometry::Rotation.

Returns:

Raises:

  • (ArgumentError)

80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/aurora-geometry/rotation.rb', line 80

def matrix
    return nil unless [@x, @y, @z].compact.size >= 2

    # Force all axes to be Vectors
    x,y,z = [@x, @y, @z].map {|a| a.is_a?(Array) ? Vector[*a] : a}

    # Force all axes to exist
    if x and y
	z = x ** y
    elsif x and z
	y = x ** z
    elsif y and z
	x = y ** z
    end

    rows = []
    [x, y, z].each_with_index {|a, i| rows.push(a.to_a) if i < @dimensions }

    raise ArgumentError, "Number of axes must match the dimensions of each axis" unless @dimensions == rows.size

    Matrix[*rows]
end

#xObject (readonly)

Returns the value of attribute x.


19
20
21
# File 'lib/aurora-geometry/rotation.rb', line 19

def x
  @x
end

#yObject (readonly)

Returns the value of attribute y.


19
20
21
# File 'lib/aurora-geometry/rotation.rb', line 19

def y
  @y
end

#zObject (readonly)

Returns the value of attribute z.


19
20
21
# File 'lib/aurora-geometry/rotation.rb', line 19

def z
  @z
end

Class Method Details

.new(angle) ⇒ Object

Create a planar Geometry::Rotation with an angle

[View source]

23
24
25
26
27
28
29
30
31
32
33
# File 'lib/aurora-geometry/rotation.rb', line 23

def self.new(*args)
    options = args.select {|a| a.is_a? Hash}.reduce({}, :merge)

    if options.has_key? :angle
	RotationAngle.new options[:angle]
elsif options.has_key?(:x) && [:x, :y, :z].one? {|k| options.has_key? k }
	RotationAngle.new x:options[:x]
    else
	self.allocate.tap {|rotation| rotation.send :initialize, *args }
    end
end

Instance Method Details

#eql?(other) ⇒ Boolean Also known as: ==

Returns:

  • (Boolean)
[View source]

69
70
71
# File 'lib/aurora-geometry/rotation.rb', line 69

def eql?(other)
    (self.x.eql? other.x) && (self.y.eql? other.y) && (self.z.eql? other.z)
end

#identity?Boolean

Returns:

  • (Boolean)
[View source]

74
75
76
# File 'lib/aurora-geometry/rotation.rb', line 74

def identity?
    (!@x && !@y && !@z) || ([@x, @y, @z].select {|a| a}.all? {|a| a.respond_to?(:magnitude) ? (1 == a.magnitude) : (1 == a.size)})
end

#transform(point) ⇒ Point

Transform and return a new Point

Parameters:

  • point (Point)

    the Point to rotate into the parent coordinate frame

Returns:

[View source]

107
108
109
110
# File 'lib/aurora-geometry/rotation.rb', line 107

def transform(point)
    m = matrix
    m ? Point[m * Point[point]] : point
end