class RMath3D::RMtx3
Document-class: RMath3D::RMtx3
provies 3x3 matrix arithmetic.
Notice
-
elements are stored in column-major order.
Public Class Methods
Creates a new 3x3 matrix.
# File lib/rmath3d/rmath3d_plain.rb, line 553 def initialize( *a ) # [NOTE] elemetns are stored in column-major order. @e = [] case a.length when 0 @e = [ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 ] when 1 case a[0] when Float, Integer @e = [ a[0], a[0], a[0], a[0], a[0], a[0], a[0], a[0], a[0] ] when RMtx3 # Copy Constructor @e = [ a[0].e00, a[0].e10, a[0].e20, a[0].e01, a[0].e11, a[0].e21, a[0].e02, a[0].e12, a[0].e22 ] else raise TypeError, "RMtx3#initialize : Unknown type #{a[0].class}." return nil end when 9 # Element-wise setter for row in 0...3 do for col in 0...3 do index = 3*row + col case a[index] when Float, Integer setElement( row, col, a[index] ) else raise TypeError, "RMtx3#initialize : Unknown type #{a[0].class}." return nil end end end else raise RuntimeError, "RMtx3#initialize : wrong # of arguments (#{a.length})" return nil end return self end
Public Instance Methods
mtx1 * mtx2 : Binary multiply operator.
# File lib/rmath3d/rmath3d_plain.rb, line 1099 def *( arg ) case arg when Float, Integer return RMtx3.new( arg*self.e00, arg*self.e01, arg*self.e02, arg*self.e10, arg*self.e11, arg*self.e12, arg*self.e20, arg*self.e21, arg*self.e22 ) when RMtx3 result = RMtx3.new for row in 0...3 do for col in 0...3 do sum = 0.0 for i in 0...3 do sum += getElement( row, i ) * arg.getElement( i, col ) end result.setElement( row, col, sum ) end end return result else raise TypeError, "RMtx3#*(arg) : Unknown type #{arg.class} given." return nil end end
mtx1 + mtx2 : Binary plus operator.
# File lib/rmath3d/rmath3d_plain.rb, line 1057 def +( arg ) if ( arg.class != RMtx3 ) raise TypeError, "RMtx3#+(arg) : Unknown type #{arg.class} given as RMtx3." return nil end result = RMtx3.new for row in 0...3 do for col in 0...3 do result.setElement( row, col, getElement(row,col) + arg.getElement(row,col) ) end end return result end
+mtx : Unary plus operator.
# File lib/rmath3d/rmath3d_plain.rb, line 1039 def +@ return self end
mtx1 - mtx2 : Binary minus operator.
# File lib/rmath3d/rmath3d_plain.rb, line 1078 def -( arg ) if ( arg.class != RMtx3 ) raise TypeError, "RMtx3#-(arg) : Unknown type #{arg.class} given as RMtx3." return nil end result = RMtx3.new for row in 0...3 do for col in 0...3 do result.setElement( row, col, getElement(row,col) - arg.getElement(row,col) ) end end return result end
-mtx : Unary minus operator.
# File lib/rmath3d/rmath3d_plain.rb, line 1048 def -@ return RMtx3.new( self * -1.0 ) end
mtx1 == mtx2 : evaluates equality.
# File lib/rmath3d/rmath3d_plain.rb, line 1130 def ==( other ) if other.class == RMtx3 for row in 0...3 do for col in 0...3 do if ( (getElement(row,col) - other.getElement(row,col)).abs > TOLERANCE ) return false end end end return true else return false end end
Returns the element at (row
,col
).
# File lib/rmath3d/rmath3d_plain.rb, line 668 def [](row,col) # [NOTE] elemetns are stored in column-major order. return @e[col*3+row] end
Stores value
at (row
,col
).
# File lib/rmath3d/rmath3d_plain.rb, line 657 def []=(row,col,value) # [NOTE] elemetns are stored in column-major order. @e[col*3+row] = value end
mtx1 += mtx2 : appends the elements of mtx2
into corresponding mtx1
elements.
# File lib/rmath3d/rmath3d_plain.rb, line 1150 def add!( other ) if ( other.class != RMtx3 ) raise TypeError, "RMtx3#add! : Unknown type #{other.class} given as RMtx3." return nil end result = RMtx3.new for row in 0...3 do for col in 0...3 do self.setElement( row, col, getElement(row,col) + other.getElement(row,col) ) end end return self end
Resolves type mismatch.
# File lib/rmath3d/rmath3d_plain.rb, line 623 def coerce case arg when Float, Integer return [ self, arg ] else raise TypeError, "RMtx3#coerce : #{arg.self} can't be coerced into #{self.class}." return nil end end
Returns the element at row 0 and column 0.
# File lib/rmath3d/rmath3d_plain.rb, line 675 def e00() getElement(0,0) end
Replaces the element at row 0 and column 0 by value
.
# File lib/rmath3d/rmath3d_plain.rb, line 694 def e00=(value) setElement(0,0,value) end
Returns the element at row 0 and column 1.
# File lib/rmath3d/rmath3d_plain.rb, line 677 def e01() getElement(0,1) end
Replaces the element at row 0 and column 1 by value
.
# File lib/rmath3d/rmath3d_plain.rb, line 696 def e01=(value) setElement(0,1,value) end
Returns the element at row 0 and column 2.
# File lib/rmath3d/rmath3d_plain.rb, line 679 def e02() getElement(0,2) end
Replaces the element at row 0 and column 2 by value
.
# File lib/rmath3d/rmath3d_plain.rb, line 698 def e02=(value) setElement(0,2,value) end
Returns the element at row 1 and column 0.
# File lib/rmath3d/rmath3d_plain.rb, line 681 def e10() getElement(1,0) end
Replaces the element at row 1 and column 0 by value
.
# File lib/rmath3d/rmath3d_plain.rb, line 700 def e10=(value) setElement(1,0,value) end
Returns the element at row 1 and column 1.
# File lib/rmath3d/rmath3d_plain.rb, line 683 def e11() getElement(1,1) end
Replaces the element at row 1 and column 1 by value
.
# File lib/rmath3d/rmath3d_plain.rb, line 702 def e11=(value) setElement(1,1,value) end
Returns the element at row 1 and column 2.
# File lib/rmath3d/rmath3d_plain.rb, line 685 def e12() getElement(1,2) end
Replaces the element at row 1 and column 2 by value
.
# File lib/rmath3d/rmath3d_plain.rb, line 704 def e12=(value) setElement(1,2,value) end
Returns the element at row 2 and column 0.
# File lib/rmath3d/rmath3d_plain.rb, line 687 def e20() getElement(2,0) end
Replaces the element at row 2 and column 0 by value
.
# File lib/rmath3d/rmath3d_plain.rb, line 706 def e20=(value) setElement(2,0,value) end
Returns the element at row 2 and column 1.
# File lib/rmath3d/rmath3d_plain.rb, line 689 def e21() getElement(2,1) end
Replaces the element at row 2 and column 1 by value
.
# File lib/rmath3d/rmath3d_plain.rb, line 708 def e21=(value) setElement(2,1,value) end
Returns the element at row 2 and column 2.
# File lib/rmath3d/rmath3d_plain.rb, line 691 def e22() getElement(2,2) end
Replaces the element at row 2 and column 2 by value
.
# File lib/rmath3d/rmath3d_plain.rb, line 710 def e22=(value) setElement(2,2,value) end
Returns c
-th column vector.
# File lib/rmath3d/rmath3d_plain.rb, line 727 def getColumn( column ) return RVec3.new( self[0,column], self[1,column], self[2,column] ) end
Calculates determinant.
# File lib/rmath3d/rmath3d_plain.rb, line 789 def getDeterminant e00 * (e11*e22 - e12*e21) - e01 * (e10*e22 - e12*e20) + e02 * (e10*e21 - e11*e20) end
Returns the inverse.
# File lib/rmath3d/rmath3d_plain.rb, line 822 def getInverse result = RMtx3.new result.e00 = (self.e11*self.e22 - self.e12*self.e21) result.e01 = -(self.e01*self.e22 - self.e02*self.e21) result.e02 = (self.e01*self.e12 - self.e02*self.e11) result.e10 = -(self.e10*self.e22 - self.e12*self.e20) result.e11 = (self.e00*self.e22 - self.e02*self.e20) result.e12 = -(self.e00*self.e12 - self.e02*self.e10) result.e20 = (self.e10*self.e21 - self.e11*self.e20) result.e21 = -(self.e00*self.e21 - self.e01*self.e20) result.e22 = (self.e00*self.e11 - self.e01*self.e10) det = e00 * result.e00 + e01 * result.e10 + e02 * result.e20 if ( det.abs < TOLERANCE ) raise RuntimeError, "RMtx3#getInverse : det.abs < TOLERANCE" return nil end d = 1.0 / det result.mul!( d ) return result end
Returns r
-th row vector.
# File lib/rmath3d/rmath3d_plain.rb, line 718 def getRow( row ) return RVec3.new( self[row,0], self[row,1], self[row,2] ) end
Returns transposed matrix.
# File lib/rmath3d/rmath3d_plain.rb, line 800 def getTransposed return RMtx3.new( @e[0], @e[1], @e[2], @e[3], @e[4], @e[5], @e[6], @e[7], @e[8] ) end
Makes itself as the inverse of the original matrix.
# File lib/rmath3d/rmath3d_plain.rb, line 856 def invert! elements = Array.new( 9 ) elements[3*0+0] = (self.e11*self.e22 - self.e12*self.e21) elements[3*0+1] = -(self.e01*self.e22 - self.e02*self.e21) elements[3*0+2] = (self.e01*self.e12 - self.e02*self.e11) elements[3*1+0] = -(self.e10*self.e22 - self.e12*self.e20) elements[3*1+1] = (self.e00*self.e22 - self.e02*self.e20) elements[3*1+2] = -(self.e00*self.e12 - self.e02*self.e10) elements[3*2+0] = (self.e10*self.e21 - self.e11*self.e20) elements[3*2+1] = -(self.e00*self.e21 - self.e01*self.e20) elements[3*2+2] = (self.e00*self.e11 - self.e01*self.e10) det = e00 * elements[3*0+0] + e01 * elements[3*1+0] + e02 * elements[3*2+0] if ( det.abs < TOLERANCE ) raise RuntimeError, "RMtx3#invert! : det.abs < TOLERANCE" return nil end d = 1.0 / det setElement( 0, 0, d * elements[3*0+0] ) setElement( 0, 1, d * elements[3*0+1] ) setElement( 0, 2, d * elements[3*0+2] ) setElement( 1, 0, d * elements[3*1+0] ) setElement( 1, 1, d * elements[3*1+1] ) setElement( 1, 2, d * elements[3*1+2] ) setElement( 2, 0, d * elements[3*2+0] ) setElement( 2, 1, d * elements[3*2+1] ) setElement( 2, 2, d * elements[3*2+2] ) return self end
mtx1 *= mtx2
# File lib/rmath3d/rmath3d_plain.rb, line 1192 def mul!( other ) case other when Float, Integer self.e00 = other*self.e00 self.e01 = other*self.e01 self.e02 = other*self.e02 self.e10 = other*self.e10 self.e11 = other*self.e11 self.e12 = other*self.e12 self.e20 = other*self.e20 self.e21 = other*self.e21 self.e22 = other*self.e22 return self when RMtx3 result = RMtx3.new for row in 0...3 do for col in 0...3 do sum = 0.0 for i in 0...3 do sum += getElement( row, i ) * other.getElement( i, col ) end result.setElement( row, col, sum ) end end self.e00 = result.e00 self.e01 = result.e01 self.e02 = result.e02 self.e10 = result.e10 self.e11 = result.e11 self.e12 = result.e12 self.e20 = result.e20 self.e21 = result.e21 self.e22 = result.e22 return self end end
Makes a matrix that rotates around the axis
.
# File lib/rmath3d/rmath3d_plain.rb, line 952 def rotationAxis( axis, radian ) if ( axis.class != RVec3 ) raise TypeError, "RMtx3#rotationAxis : Unknown type #{axis.class} given as axis." return nil end s = Math.sin( radian ) c = Math.cos( radian ) omc = 1.0 - c x = axis.x.to_f y = axis.y.to_f z = axis.z.to_f self.e00 = x*x*omc + c self.e01 = x*y*omc - z*s self.e02 = z*x*omc + y*s self.e10 = x*y*omc + z*s self.e11 = y*y*omc + c self.e12 = y*z*omc - x*s self.e20 = z*x*omc - y*s self.e21 = y*z*omc + x*s self.e22 = z*z*omc + c return self end
Makes a rotation matrix from a normalized quaternion q
.
# File lib/rmath3d/rmath3d_plain.rb, line 982 def rotationQuaternion( q ) if ( q.class != RQuat ) raise TypeError, "RMtx3#rotationQuaternion : Unknown type #{q.class} given as RQuat." return nil end x = q.x y = q.y z = q.z w = q.w x2 = 2.0 * x y2 = 2.0 * y z2 = 2.0 * z xx2 = x * x2 yy2 = y * y2 zz2 = z * z2 yz2 = y * z2 wx2 = w * x2 xy2 = x * y2 wz2 = w * z2 xz2 = x * z2 wy2 = w * y2 self.e00 = 1.0 - yy2 - zz2 self.e10 = xy2 + wz2 self.e20 = xz2 - wy2 self.e01 = xy2 - wz2 self.e11 = 1.0 - xx2 - zz2 self.e21 = yz2 + wx2 self.e02 = xz2 + wy2 self.e12 = yz2 - wx2 self.e22 = 1.0 - xx2 - yy2 return self end
Makes a matrix that rotates around the x-axis.
# File lib/rmath3d/rmath3d_plain.rb, line 898 def rotationX( radian ) s = Math.sin( radian ) c = Math.cos( radian ) setIdentity() self.e11 = c self.e12 = -s self.e21 = s self.e22 = c return self end
Makes a matrix that rotates around the y-axis.
# File lib/rmath3d/rmath3d_plain.rb, line 916 def rotationY( radian ) s = Math.sin( radian ) c = Math.cos( radian ) setIdentity() self.e00 = c self.e02 = s self.e20 = -s self.e22 = c return self end
Makes a matrix that rotates around the z-axis.
# File lib/rmath3d/rmath3d_plain.rb, line 934 def rotationZ( radian ) s = Math.sin( radian ) c = Math.cos( radian ) setIdentity() self.e00 = c self.e01 = -s self.e10 = s self.e11 = c return self end
Makes itself as a scaling matrix.
# File lib/rmath3d/rmath3d_plain.rb, line 1025 def scaling( sx, sy, sz ) setIdentity() setElement( 0, 0, sx ) setElement( 1, 1, sy ) setElement( 2, 2, sz ) return self end
Returns sets c
-th column by vector v
.
# File lib/rmath3d/rmath3d_plain.rb, line 747 def setColumn( v, column ) self[0,column] = v.x self[1,column] = v.y self[2,column] = v.z end
Stores given 9 new values.
# File lib/rmath3d/rmath3d_plain.rb, line 638 def setElements( *a ) if a.length != 9 raise RuntimeError, "RMtx3#setElements : wrong # of arguments (#{a.length})" return nil end for row in 0...3 do for col in 0...3 do index = 3*row + col setElement( row, col, a[index] ) end end end
Sets as identity matrix.
# File lib/rmath3d/rmath3d_plain.rb, line 770 def setIdentity for row in 0...3 do for col in 0...3 do index = 3*row + col if ( row == col ) setElement( row, col, 1.0 ) else setElement( row, col, 0.0 ) end end end return self end
Returns sets r
-th row by vector v
.
# File lib/rmath3d/rmath3d_plain.rb, line 736 def setRow( v, row ) self[row,0] = v.x self[row,1] = v.y self[row,2] = v.z end
Clears all elements by 0.0
# File lib/rmath3d/rmath3d_plain.rb, line 758 def setZero 9.times do |i| @e[i] = 0.0 end return self end
mtx1 -= mtx2 : subtracts the elements of mtx2
from corresponding mtx1
elements.
# File lib/rmath3d/rmath3d_plain.rb, line 1171 def sub!( other ) if ( other.class != RMtx3 ) raise TypeError, "RMtx3#sub! : Unknown type #{other.class} given as RMtx3." return nil end result = RMtx3.new for row in 0...3 do for col in 0...3 do self.setElement( row, col, getElement(row,col) - other.getElement(row,col) ) end end return self end
Returns its elements as a new Array.
# File lib/rmath3d/rmath3d_plain.rb, line 614 def to_a return @e end
Returns human-readable string.
# File lib/rmath3d/rmath3d_plain.rb, line 603 def to_s "( #{@e[0]}, #{@e[3]}, #{@e[6]} )\n" + "( #{@e[1]}, #{@e[4]}, #{@e[7]} )\n" + "( #{@e[2]}, #{@e[5]}, #{@e[8]} )\n" end
Transposeas its elements.
# File lib/rmath3d/rmath3d_plain.rb, line 811 def transpose! @e[1], @e[3] = @e[3], @e[1] @e[2], @e[6] = @e[6], @e[2] @e[5], @e[7] = @e[7], @e[5] end