Class: Geometry::Transformation

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

Overview

Transformation represents a relationship between two coordinate frames

To create a pure translation relationship:

translate = Geometry::Transformation.new(:translate => Point[4, 2])

To create a transformation with an origin and an X-axis aligned with the parent coordinate system’s Y-axis (the Y and Z axes will be chosen arbitrarily):

translate = Geometry::Transformation.new(:origin => [4, 2], :x => [0,1,0])

To create a transformation with an origin, an X-axis aligned with the parent coordinate system’s Y-axis, and a Y-axis aligned with the parent coordinate system’s X-axis:

translate = Geometry::Transformation.new(:origin => [4, 2], :x => [0,1,0], :y => [1,0,0])

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(*args) ⇒ Transformation

Returns a new instance of Transformation.

Parameters:

  • options (Hash)

    a customizable set of options



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/geometry/transformation.rb', line 46

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

    @dimensions = options[:dimensions] || nil

    @rotation = options[:rotate] || rotate || Geometry::Rotation.new(options)
    @scale = options[:scale] || scale

    case options.count {|k,v| [:move, :origin, :translate].include? k }
	when 0
	    @translation = translate
	when 1
	    @translation = (options[:translate] ||= options.delete(:move) || options.delete(:origin))
	else
	    raise ArgumentError, "Too many translation parameters in #{options}"
    end

    @translation = Point[*@translation]
    if @translation
	@translation = nil if @translation.all? {|v| v == 0}
	raise ArgumentError, ":translate must be a Point or a Vector" if @translation and not @translation.is_a?(Vector)
    end

    if @dimensions
	biggest = [@translation, @scale].select {|a| a}.map {|a| a.size}.max

	if biggest and (biggest != 0) and (((biggest != @dimensions)) or (@rotation and (@rotation.dimensions != biggest)))
	    raise ArgumentError, "Dimensionality mismatch"
	end
    end
end

Instance Attribute Details

#dimensionsObject (readonly)

Returns the value of attribute dimensions.



24
25
26
# File 'lib/geometry/transformation.rb', line 24

def dimensions
  @dimensions
end

#rotationObject (readonly)

Returns the value of attribute rotation.



25
26
27
# File 'lib/geometry/transformation.rb', line 25

def rotation
  @rotation
end

#scaleObject (readonly)

Returns the value of attribute scale.



26
27
28
# File 'lib/geometry/transformation.rb', line 26

def scale
  @scale
end

#translationObject (readonly)

Returns the value of attribute translation.



27
28
29
# File 'lib/geometry/transformation.rb', line 27

def translation
  @translation
end

#x_axisObject (readonly)

Returns the value of attribute x_axis.



29
30
31
# File 'lib/geometry/transformation.rb', line 29

def x_axis
  @x_axis
end

#y_axisObject (readonly)

Returns the value of attribute y_axis.



29
30
31
# File 'lib/geometry/transformation.rb', line 29

def y_axis
  @y_axis
end

#z_axisObject (readonly)

Returns the value of attribute z_axis.



29
30
31
# File 'lib/geometry/transformation.rb', line 29

def z_axis
  @z_axis
end

Instance Method Details

#+(other) ⇒ Object

Compose the current Geometry::Transformation with another one



91
92
93
94
95
96
97
98
99
# File 'lib/geometry/transformation.rb', line 91

def +(other)
    if other.is_a?(Array) or other.is_a?(Vector)
	if @translation
	    Transformation.new(@translation+other, @rotation, @scale)
	else
	    Transformation.new(other, @rotation, @scale)
	end
    end
end

#-(other) ⇒ Object



101
102
103
104
105
106
107
108
109
# File 'lib/geometry/transformation.rb', line 101

def -(other)
    if other.is_a?(Array) or other.is_a?(Vector)
	if @translation
	    Transformation.new(@translation-other, @rotation, @scale)
	else
	    Transformation.new(other.map {|e| -e}, @rotation, @scale)
	end
    end
end

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

Returns:

  • (Boolean)


85
86
87
# File 'lib/geometry/transformation.rb', line 85

def eql?(other)
    (self.rotation.eql? other.rotation) && (self.scale.eql? other.scale) && (self.translation.eql? other.translation)
end

#identity?Boolean

Returns true if the Geometry::Transformation is the identity transformation

Returns:

  • (Boolean)


81
82
83
# File 'lib/geometry/transformation.rb', line 81

def identity?
    @rotation.identity? && !(@scale || @translation)
end

#transform(point) ⇒ Point

Transform and return a new Point

Parameters:

Returns:



114
115
116
# File 'lib/geometry/transformation.rb', line 114

def transform(point)
    @translation + point
end