class RMath3D::RMtx4
Document-class: RMath3D::RMtx4
provies 4x4 matrix arithmetic.
Notice
-
elements are stored in column-major order.
Public Class Methods
Creates a new 4x4 matrix.
# File lib/rmath3d/rmath3d_plain.rb, line 1251 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, 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], a[0], a[0], a[0], a[0], a[0], a[0], a[0] ] when RMtx4 # Copy Constructor @e = [ a[0].e00, a[0].e10, a[0].e20, a[0].e30, a[0].e01, a[0].e11, a[0].e21, a[0].e31, a[0].e02, a[0].e12, a[0].e22, a[0].e32, a[0].e03, a[0].e13, a[0].e23, a[0].e33 ] else raise TypeError, "RMtx4#initialize : Unknown type #{a[0].class}." return nil end when 16 # Element-wise setter for row in 0...4 do for col in 0...4 do index = 4*row + col case a[index] when Float, Integer setElement( row, col, a[index] ) else raise TypeError, "RMtx4#initialize : Unknown type #{a[0].class}." return nil end end end else raise RuntimeError, "RMtx4#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 2187 def *( arg ) case arg when Float, Integer return RMtx4.new( arg*self.e00, arg*self.e01, arg*self.e02, arg*self.e03, arg*self.e10, arg*self.e11, arg*self.e12, arg*self.e13, arg*self.e20, arg*self.e21, arg*self.e22, arg*self.e23, arg*self.e30, arg*self.e31, arg*self.e32, arg*self.e33 ) when RMtx4 result = RMtx4.new for row in 0...4 do for col in 0...4 do sum = 0.0 for i in 0...4 do sum += getElement( row, i ) * arg.getElement( i, col ) end result.setElement( row, col, sum ) end end return result else raise TypeError, "RMtx4#*(arg) : Unknown type #{arg.class} given." return nil end end
mtx1 + mtx2 : Binary plus operator.
# File lib/rmath3d/rmath3d_plain.rb, line 2145 def +( arg ) if ( arg.class != RMtx4 ) raise TypeError, "RMtx4#+(arg) : Unknown type #{arg.class} given as RMtx4." return nil end result = RMtx4.new for row in 0...4 do for col in 0...4 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 2127 def +@ return self end
mtx1 - mtx2 : Binary minus operator.
# File lib/rmath3d/rmath3d_plain.rb, line 2166 def -( arg ) if ( arg.class != RMtx4 ) raise TypeError, "RMtx4#-(arg) : Unknown type #{arg.class} given as RMtx4." return nil end result = RMtx4.new for row in 0...4 do for col in 0...4 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 2136 def -@ return RMtx4.new( self * -1.0 ) end
mtx1 == mtx2 : evaluates equality.
# File lib/rmath3d/rmath3d_plain.rb, line 2219 def ==( other ) if other.class == RMtx4 for row in 0...4 do for col in 0...4 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 1370 def [](row,col) # [NOTE] elemetns are stored in column-major order. return @e[col*4+row] end
Stores value
at (row
,col
).
# File lib/rmath3d/rmath3d_plain.rb, line 1359 def []=(row,col,value) # [NOTE] elemetns are stored in column-major order. @e[col*4+row] = value end
mtx1 += mtx2 : appends the elements of mtx2
into corresponding mtx1
elements.
# File lib/rmath3d/rmath3d_plain.rb, line 2239 def add!( other ) if ( other.class != RMtx4 ) raise TypeError, "RMtx4#add! : Unknown type #{other.class} given as RMtx4." return nil end result = RMtx4.new for row in 0...4 do for col in 0...4 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 1325 def coerce case arg when Float, Integer return [ self, arg ] else raise TypeError, "RMtx4#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 1377 def e00() getElement(0,0) end
Replaces the element at row 0 and column 0 by value
.
# File lib/rmath3d/rmath3d_plain.rb, line 1410 def e00=(value) setElement(0,0,value) end
Returns the element at row 0 and column 1.
# File lib/rmath3d/rmath3d_plain.rb, line 1379 def e01() getElement(0,1) end
Replaces the element at row 0 and column 1 by value
.
# File lib/rmath3d/rmath3d_plain.rb, line 1412 def e01=(value) setElement(0,1,value) end
Returns the element at row 0 and column 2.
# File lib/rmath3d/rmath3d_plain.rb, line 1381 def e02() getElement(0,2) end
Replaces the element at row 0 and column 2 by value
.
# File lib/rmath3d/rmath3d_plain.rb, line 1414 def e02=(value) setElement(0,2,value) end
Returns the element at row 0 and column 3.
# File lib/rmath3d/rmath3d_plain.rb, line 1383 def e03() getElement(0,3) end
Replaces the element at row 0 and column 3 by value
.
# File lib/rmath3d/rmath3d_plain.rb, line 1416 def e03=(value) setElement(0,3,value) end
Returns the element at row 1 and column 0.
# File lib/rmath3d/rmath3d_plain.rb, line 1385 def e10() getElement(1,0) end
Replaces the element at row 1 and column 0 by value
.
# File lib/rmath3d/rmath3d_plain.rb, line 1418 def e10=(value) setElement(1,0,value) end
Returns the element at row 1 and column 1.
# File lib/rmath3d/rmath3d_plain.rb, line 1387 def e11() getElement(1,1) end
Replaces the element at row 1 and column 1 by value
.
# File lib/rmath3d/rmath3d_plain.rb, line 1420 def e11=(value) setElement(1,1,value) end
Returns the element at row 1 and column 2.
# File lib/rmath3d/rmath3d_plain.rb, line 1389 def e12() getElement(1,2) end
Replaces the element at row 1 and column 2 by value
.
# File lib/rmath3d/rmath3d_plain.rb, line 1422 def e12=(value) setElement(1,2,value) end
Returns the element at row 1 and column 3.
# File lib/rmath3d/rmath3d_plain.rb, line 1391 def e13() getElement(1,3) end
Replaces the element at row 1 and column 3 by value
.
# File lib/rmath3d/rmath3d_plain.rb, line 1424 def e13=(value) setElement(1,3,value) end
Returns the element at row 2 and column 0.
# File lib/rmath3d/rmath3d_plain.rb, line 1393 def e20() getElement(2,0) end
Replaces the element at row 2 and column 0 by value
.
# File lib/rmath3d/rmath3d_plain.rb, line 1426 def e20=(value) setElement(2,0,value) end
Returns the element at row 2 and column 1.
# File lib/rmath3d/rmath3d_plain.rb, line 1395 def e21() getElement(2,1) end
Replaces the element at row 2 and column 1 by value
.
# File lib/rmath3d/rmath3d_plain.rb, line 1428 def e21=(value) setElement(2,1,value) end
Returns the element at row 2 and column 2.
# File lib/rmath3d/rmath3d_plain.rb, line 1397 def e22() getElement(2,2) end
Replaces the element at row 2 and column 2 by value
.
# File lib/rmath3d/rmath3d_plain.rb, line 1430 def e22=(value) setElement(2,2,value) end
Returns the element at row 2 and column 3.
# File lib/rmath3d/rmath3d_plain.rb, line 1399 def e23() getElement(2,3) end
Replaces the element at row 2 and column 3 by value
.
# File lib/rmath3d/rmath3d_plain.rb, line 1432 def e23=(value) setElement(2,3,value) end
Returns the element at row 3 and column 0.
# File lib/rmath3d/rmath3d_plain.rb, line 1401 def e30() getElement(3,0) end
Replaces the element at row 3 and column 0 by value
.
# File lib/rmath3d/rmath3d_plain.rb, line 1434 def e30=(value) setElement(3,0,value) end
Returns the element at row 3 and column 1.
# File lib/rmath3d/rmath3d_plain.rb, line 1403 def e31() getElement(3,1) end
Replaces the element at row 3 and column 1 by value
.
# File lib/rmath3d/rmath3d_plain.rb, line 1436 def e31=(value) setElement(3,1,value) end
Returns the element at row 3 and column 2.
# File lib/rmath3d/rmath3d_plain.rb, line 1405 def e32() getElement(3,2) end
Replaces the element at row 3 and column 2 by value
.
# File lib/rmath3d/rmath3d_plain.rb, line 1438 def e32=(value) setElement(3,2,value) end
Returns the element at row 3 and column 3.
# File lib/rmath3d/rmath3d_plain.rb, line 1407 def e33() getElement(3,3) end
Replaces the element at row 3 and column 3 by value
.
# File lib/rmath3d/rmath3d_plain.rb, line 1440 def e33=(value) setElement(3,3,value) end
Returns c
-th column vector.
# File lib/rmath3d/rmath3d_plain.rb, line 1456 def getColumn( column ) return RVec4.new( self[0,column], self[1,column], self[2,column], self[3,column] ) end
Calculates determinant.
# File lib/rmath3d/rmath3d_plain.rb, line 1546 def getDeterminant e00 * det3( e11,e12,e13, e21,e22,e23, e31,e32,e33 ) - e01 * det3( e10,e12,e13, e20,e22,e23, e30,e32,e33 ) + e02 * det3( e10,e11,e13, e20,e21,e23, e30,e31,e33 ) - e03 * det3( e10,e11,e12, e20,e21,e22, e30,e31,e32 ) end
Returns the inverse.
# File lib/rmath3d/rmath3d_plain.rb, line 1584 def getInverse result = RMtx4.new result.e00 = det3( e11,e12,e13, e21,e22,e23, e31,e32,e33 ) result.e01 = -det3( e01,e02,e03, e21,e22,e23, e31,e32,e33 ) result.e02 = det3( e01,e02,e03, e11,e12,e13, e31,e32,e33 ) result.e03 = -det3( e01,e02,e03, e11,e12,e13, e21,e22,e23 ) result.e10 = -det3( e10,e12,e13, e20,e22,e23, e30,e32,e33 ) result.e11 = det3( e00,e02,e03, e20,e22,e23, e30,e32,e33 ) result.e12 = -det3( e00,e02,e03, e10,e12,e13, e30,e32,e33 ) result.e13 = det3( e00,e02,e03, e10,e12,e13, e20,e22,e23 ) result.e20 = det3( e10,e11,e13, e20,e21,e23, e30,e31,e33 ) result.e21 = -det3( e00,e01,e03, e20,e21,e23, e30,e31,e33 ) result.e22 = det3( e00,e01,e03, e10,e11,e13, e30,e31,e33 ) result.e23 = -det3( e00,e01,e03, e10,e11,e13, e20,e21,e23 ) result.e30 = -det3( e10,e11,e12, e20,e21,e22, e30,e31,e32 ) result.e31 = det3( e00,e01,e02, e20,e21,e22, e30,e31,e32 ) result.e32 = -det3( e00,e01,e02, e10,e11,e12, e30,e31,e32 ) result.e33 = det3( e00,e01,e02, e10,e11,e12, e20,e21,e22 ) det = e00 * result.e00 + e01 * result.e10 + e02 * result.e20 + e03 * result.e30 if ( det.abs < TOLERANCE ) raise RuntimeError, "RMtx4#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 1447 def getRow( row ) return RVec4.new( self[row,0], self[row,1], self[row,2], self[row,3] ) end
Returns transposed matrix.
# File lib/rmath3d/rmath3d_plain.rb, line 1558 def getTransposed return RMtx4.new( @e[ 0], @e[ 1], @e[ 2], @e[ 3], @e[ 4], @e[ 5], @e[ 6], @e[ 7], @e[ 8], @e[ 9], @e[10], @e[11], @e[12], @e[13], @e[14], @e[15] ) end
# File lib/rmath3d/rmath3d_plain.rb, line 1484 def getUpper3x3 return RMtx3.new( self.e00, self.e01, self.e02, self.e10, self.e11, self.e12, self.e20, self.e21, self.e22 ) end
Makes itself as the inverse of the original matrix.
# File lib/rmath3d/rmath3d_plain.rb, line 1626 def invert! elements = Array.new( 16 ) elements[4*0+0] = det3( self.e11,self.e12,self.e13, self.e21,self.e22,self.e23, self.e31,self.e32,self.e33 ) elements[4*0+1] = -det3( self.e01,self.e02,self.e03, self.e21,self.e22,self.e23, self.e31,self.e32,self.e33 ) elements[4*0+2] = det3( self.e01,self.e02,self.e03, self.e11,self.e12,self.e13, self.e31,self.e32,self.e33 ) elements[4*0+3] = -det3( self.e01,self.e02,self.e03, self.e11,self.e12,self.e13, self.e21,self.e22,self.e23 ) elements[4*1+0] = -det3( self.e10,self.e12,self.e13, self.e20,self.e22,self.e23, self.e30,self.e32,self.e33 ) elements[4*1+1] = det3( self.e00,self.e02,self.e03, self.e20,self.e22,self.e23, self.e30,self.e32,self.e33 ) elements[4*1+2] = -det3( self.e00,self.e02,self.e03, self.e10,self.e12,self.e13, self.e30,self.e32,self.e33 ) elements[4*1+3] = det3( self.e00,self.e02,self.e03, self.e10,self.e12,self.e13, self.e20,self.e22,self.e23 ) elements[4*2+0] = det3( self.e10,self.e11,self.e13, self.e20,self.e21,self.e23, self.e30,self.e31,self.e33 ) elements[4*2+1] = -det3( self.e00,self.e01,self.e03, self.e20,self.e21,self.e23, self.e30,self.e31,self.e33 ) elements[4*2+2] = det3( self.e00,self.e01,self.e03, self.e10,self.e11,self.e13, self.e30,self.e31,self.e33 ) elements[4*2+3] = -det3( self.e00,self.e01,self.e03, self.e10,self.e11,self.e13, self.e20,self.e21,self.e23 ) elements[4*3+0] = -det3( self.e10,self.e11,self.e12, self.e20,self.e21,self.e22, self.e30,self.e31,self.e32 ) elements[4*3+1] = det3( self.e00,self.e01,self.e02, self.e20,self.e21,self.e22, self.e30,self.e31,self.e32 ) elements[4*3+2] = -det3( self.e00,self.e01,self.e02, self.e10,self.e11,self.e12, self.e30,self.e31,self.e32 ) elements[4*3+3] = det3( self.e00,self.e01,self.e02, self.e10,self.e11,self.e12, self.e20,self.e21,self.e22 ) det = e00 * elements[4*0+0] + e01 * elements[4*1+0] + e02 * elements[4*2+0] + e03 * elements[4*3+0] if ( det.abs< TOLERANCE ) raise RuntimeError, "RMtx4invert! : det.abs < TOLERANCE" return nil end d = 1.0 / det setElement( 0, 0, d * elements[4*0+0] ) setElement( 0, 1, d * elements[4*0+1] ) setElement( 0, 2, d * elements[4*0+2] ) setElement( 0, 3, d * elements[4*0+3] ) setElement( 1, 0, d * elements[4*1+0] ) setElement( 1, 1, d * elements[4*1+1] ) setElement( 1, 2, d * elements[4*1+2] ) setElement( 1, 3, d * elements[4*1+3] ) setElement( 2, 0, d * elements[4*2+0] ) setElement( 2, 1, d * elements[4*2+1] ) setElement( 2, 2, d * elements[4*2+2] ) setElement( 2, 3, d * elements[4*2+3] ) setElement( 3, 0, d * elements[4*3+0] ) setElement( 3, 1, d * elements[4*3+1] ) setElement( 3, 2, d * elements[4*3+2] ) setElement( 3, 3, d * elements[4*3+3] ) return self end
Builds a viewing matrix for a left-handed coordinate system from:
# File lib/rmath3d/rmath3d_plain.rb, line 1848 def lookAtLH( eye, at, up ) setIdentity() axis_z = (at - eye).normalize! axis_x = RVec3.cross( up, axis_z ).normalize! axis_y = RVec3.cross( axis_z, axis_x ) self.e00 = axis_x[0] self.e01 = axis_x[1] self.e02 = axis_x[2] self.e03 = -RVec3.dot( axis_x, eye ) self.e10 = axis_y[0] self.e11 = axis_y[1] self.e12 = axis_y[2] self.e13 = -RVec3.dot( axis_y, eye ) self.e20 = axis_z[0] self.e21 = axis_z[1] self.e22 = axis_z[2] self.e23 = -RVec3.dot( axis_z, eye ) return self end
Builds a viewing matrix for a right-handed coordinate system from:
# File lib/rmath3d/rmath3d_plain.rb, line 1881 def lookAtRH( eye, at, up ) setIdentity() axis_z = (eye - at).normalize! axis_x = RVec3.cross( up, axis_z ).normalize! axis_y = RVec3.cross( axis_z, axis_x ) self.e00 = axis_x[0] self.e01 = axis_x[1] self.e02 = axis_x[2] self.e03 = -RVec3.dot( axis_x, eye ) self.e10 = axis_y[0] self.e11 = axis_y[1] self.e12 = axis_y[2] self.e13 = -RVec3.dot( axis_y, eye ) self.e20 = axis_z[0] self.e21 = axis_z[1] self.e22 = axis_z[2] self.e23 = -RVec3.dot( axis_z, eye ) return self end
mtx1 *= mtx2
# File lib/rmath3d/rmath3d_plain.rb, line 2281 def mul!( other ) case other when Float, Integer self.e00 = other*self.e00 self.e01 = other*self.e01 self.e02 = other*self.e02 self.e03 = other*self.e03 self.e10 = other*self.e10 self.e11 = other*self.e11 self.e12 = other*self.e12 self.e13 = other*self.e13 self.e20 = other*self.e20 self.e21 = other*self.e21 self.e22 = other*self.e22 self.e23 = other*self.e23 self.e30 = other*self.e30 self.e31 = other*self.e31 self.e32 = other*self.e32 self.e33 = other*self.e33 return self when RMtx4 result = RMtx4.new for row in 0...4 do for col in 0...4 do sum = 0.0 for i in 0...4 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.e03 = result.e03 self.e10 = result.e10 self.e11 = result.e11 self.e12 = result.e12 self.e13 = result.e13 self.e20 = result.e20 self.e21 = result.e21 self.e22 = result.e22 self.e23 = result.e23 self.e30 = result.e30 self.e31 = result.e31 self.e32 = result.e32 self.e33 = result.e33 return self end end
Builds a orthogonal projection matrix for a right-handed coordinate system from:
-
View volume width (
width
) -
View volume height (
height
) -
Near clip plane distance (
znear
) -
Far clip plane distance (
zfar
) -
Set true for the environment with Z coordinate ranges from -1 to +1 (OpenGL), and false otherwise (Direct3D, Metal) (
ndc_homogeneous
)
# File lib/rmath3d/rmath3d_plain.rb, line 1980 def orthoLH( width, height, znear, zfar, ndc_homogeneous = true) orthoOffCenterLH( -width/2.0, width/2.0, -height/2.0, height/2.0, znear, zfar, ndc_homogeneous ) return self end
Builds a orthogonal projection matrix for a right-handed coordinate system from:
-
Minimum value of the view volume width (
left
) -
Maximum value of the view volume width (
right
) -
Minimum value of the view volume height (
bottom
) -
Maximum value of the view volume height (
top
) -
Near clip plane distance (
znear
) -
Far clip plane distance (
zfar
) -
Set true for the environment with Z coordinate ranges from -1 to +1 (OpenGL), and false otherwise (Direct3D, Metal) (
ndc_homogeneous
)
# File lib/rmath3d/rmath3d_plain.rb, line 1997 def orthoOffCenterLH( left, right, bottom, top, znear, zfar, ndc_homogeneous = true) tx = -(right+left) / (right-left) ty = -(top+bottom) / (top-bottom) tz = ndc_homogeneous ? -(zfar+znear) / (zfar-znear) : -znear / (zfar-znear) setIdentity() setElement( 0, 0, 2.0/(right-left) ) setElement( 0, 3, tx ) setElement( 1, 1, 2.0/(top-bottom) ) setElement( 1, 3, ty ) setElement( 2, 2, (ndc_homogeneous ? 2.0 : 1.0)/(zfar-znear) ) setElement( 2, 3, tz ) return self end
Builds a orthogonal projection matrix for a right-handed coordinate system from:
-
Minimum value of the view volume width (
left
) -
Maximum value of the view volume width (
right
) -
Minimum value of the view volume height (
bottom
) -
Maximum value of the view volume height (
top
) -
Near clip plane distance (
znear
) -
Far clip plane distance (
zfar
) -
Set true for the environment with Z coordinate ranges from -1 to +1 (OpenGL), and false otherwise (Direct3D, Metal) (
ndc_homogeneous
)
# File lib/rmath3d/rmath3d_plain.rb, line 2105 def orthoOffCenterRH( left, right, bottom, top, znear, zfar, ndc_homogeneous = true) tx = -(right+left) / (right-left) ty = -(top+bottom) / (top-bottom) tz = ndc_homogeneous ? -(zfar+znear) / (zfar-znear) : -znear / (zfar-znear) setIdentity() setElement( 0, 0, 2.0/(right-left) ) setElement( 0, 3, tx ) setElement( 1, 1, 2.0/(top-bottom) ) setElement( 1, 3, ty ) setElement( 2, 2, -(ndc_homogeneous ? 2.0 : 1.0)/(zfar-znear) ) setElement( 2, 3, tz ) return self end
Builds a orthogonal projection matrix for a right-handed coordinate system from:
-
View volume width (
width
) -
View volume height (
height
) -
Near clip plane distance (
znear
) -
Far clip plane distance (
zfar
) -
Set true for the environment with Z coordinate ranges from -1 to +1 (OpenGL), and false otherwise (Direct3D, Metal) (
ndc_homogeneous
)
# File lib/rmath3d/rmath3d_plain.rb, line 2088 def orthoRH( width, height, znear, zfar, ndc_homogeneous = true) orthoOffCenterRH( -width/2.0, width/2.0, -height/2.0, height/2.0, znear, zfar, ndc_homogeneous ) return self end
Builds a perspective projection matrix for a right-handed coordinate system from:
-
Field of view in y direction (
fovy
radian) -
Aspect ratio (
aspect
) -
Near clip plane distance (
znear
) -
Far clip plane distance (
zfar
) -
Set true for the environment with Z coordinate ranges from -1 to +1 (OpenGL), and false otherwise (Direct3D, Metal) (
ndc_homogeneous
)
# File lib/rmath3d/rmath3d_plain.rb, line 1930 def perspectiveFovLH( fovy_radian, aspect, znear, zfar, ndc_homogeneous = true) # Ref.: https://www.scratchapixel.com/lessons/3d-basic-rendering/perspective-and-orthographic-projection-matrix/opengl-perspective-projection-matrix top = Math::tan(fovy_radian / 2.0) * znear bottom = -top right = top * aspect left = -right return perspectiveOffCenterLH(left, right, bottom, top, znear, zfar, ndc_homogeneous) end
Builds a perspective projection matrix for a right-handed coordinate system from:
-
Field of view in y direction (
fovy
radian) -
Aspect ratio (
aspect
) -
Near clip plane distance (
znear
) -
Far clip plane distance (
zfar
) -
Set true for the environment with Z coordinate ranges from -1 to +1 (OpenGL), and false otherwise (Direct3D, Metal) (
ndc_homogeneous
)
# File lib/rmath3d/rmath3d_plain.rb, line 2038 def perspectiveFovRH( fovy_radian, aspect, znear, zfar, ndc_homogeneous = true) # Ref.: https://www.scratchapixel.com/lessons/3d-basic-rendering/perspective-and-orthographic-projection-matrix/opengl-perspective-projection-matrix top = Math::tan(fovy_radian / 2.0) * znear bottom = -top right = top * aspect left = -right return perspectiveOffCenterRH(left, right, bottom, top, znear, zfar, ndc_homogeneous) end
Builds a perspective projection matrix for a right-handed coordinate system from:
-
View volume width (
width
) -
View volume height (
height
) -
Near clip plane distance (
znear
) -
Far clip plane distance (
zfar
) -
Set true for the environment with Z coordinate ranges from -1 to +1 (OpenGL), and false otherwise (Direct3D, Metal) (
ndc_homogeneous
)
# File lib/rmath3d/rmath3d_plain.rb, line 1916 def perspectiveLH( width, height, znear, zfar, ndc_homogeneous = true) return perspectiveOffCenterLH(-width/2.0, width/2.0, -height/2.0, height/2.0, znear, zfar, ndc_homogeneous ) end
Builds a perspective projection matrix for a right-handed coordinate system from:
-
Minimum value of the view volume width (
left
) -
Maximum value of the view volume width (
right
) -
Minimum value of the view volume height (
bottom
) -
Maximum value of the view volume height (
top
) -
Near clip plane distance (
znear
) -
Far clip plane distance (
zfar
) -
Set true for the environment with Z coordinate ranges from -1 to +1 (OpenGL), and false otherwise (Direct3D, Metal) (
ndc_homogeneous
)
# File lib/rmath3d/rmath3d_plain.rb, line 1951 def perspectiveOffCenterLH( left, right, bottom, top, znear, zfar, ndc_homogeneous = true) a = (right+left) / (right-left) b = (top+bottom) / (top-bottom) c = ndc_homogeneous ? -(zfar+znear) / (zfar-znear) : -zfar / (zfar-znear) d = ndc_homogeneous ? -(2*znear*zfar) / (zfar-znear) : -(znear*zfar) / (zfar-znear) setZero() setElement( 0, 0, 2*znear/(right-left) ) setElement( 0, 2, -a ) setElement( 1, 1, 2*znear/(top-bottom) ) setElement( 1, 2, -b ) setElement( 2, 2, -c ) setElement( 2, 3, d ) setElement( 3, 2, 1.0 ) return self end
Builds a perspective projection matrix for a right-handed coordinate system from:
-
Minimum value of the view volume width (
left
) -
Maximum value of the view volume width (
right
) -
Minimum value of the view volume height (
bottom
) -
Maximum value of the view volume height (
top
) -
Near clip plane distance (
znear
) -
Far clip plane distance (
zfar
) -
Set true for the environment with Z coordinate ranges from -1 to +1 (OpenGL), and false otherwise (Direct3D, Metal) (
ndc_homogeneous
)
# File lib/rmath3d/rmath3d_plain.rb, line 2059 def perspectiveOffCenterRH( left, right, bottom, top, znear, zfar, ndc_homogeneous = true) a = (right+left) / (right-left) b = (top+bottom) / (top-bottom) c = ndc_homogeneous ? -(zfar+znear) / (zfar-znear) : -zfar / (zfar-znear) d = ndc_homogeneous ? -(2*znear*zfar) / (zfar-znear) : -(znear*zfar) / (zfar-znear) setZero() setElement( 0, 0, 2*znear/(right-left) ) setElement( 0, 2, a ) setElement( 1, 1, 2*znear/(top-bottom) ) setElement( 1, 2, b ) setElement( 2, 2, c ) setElement( 2, 3, d ) setElement( 3, 2, -1.0 ) return self end
Builds a perspective projection matrix for a right-handed coordinate system from:
-
View volume width (
width
) -
View volume height (
height
) -
Near clip plane distance (
znear
) -
Far clip plane distance (
zfar
) -
Set true for the environment with Z coordinate ranges from -1 to +1 (OpenGL), and false otherwise (Direct3D, Metal) (
ndc_homogeneous
)
# File lib/rmath3d/rmath3d_plain.rb, line 2024 def perspectiveRH( width, height, znear, zfar, ndc_homogeneous = true) return perspectiveOffCenterRH(-width/2.0, width/2.0, -height/2.0, height/2.0, znear, zfar, ndc_homogeneous ) end
Makes a matrix that rotates around the axis
.
# File lib/rmath3d/rmath3d_plain.rb, line 1754 def rotationAxis( axis, radian ) if ( axis.class != RVec3 ) raise TypeError, "RMtx4#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 setIdentity() 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 1786 def rotationQuaternion( q ) if ( q.class != RQuat ) raise TypeError, "RMtx4#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 setIdentity() 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 1700 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 1718 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 1736 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 1831 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 1477 def setColumn( v, column ) self[0,column] = v.x self[1,column] = v.y self[2,column] = v.z self[3,column] = v.w end
Stores given 16 new values.
# File lib/rmath3d/rmath3d_plain.rb, line 1340 def setElements( *a ) if a.length != 16 raise RuntimeError, "RMtx4#setElements : wrong # of arguments (#{a.length})" return nil end for row in 0...4 do for col in 0...4 do index = 4*row + col setElement( row, col, a[index] ) end end end
Sets as identity matrix.
# File lib/rmath3d/rmath3d_plain.rb, line 1520 def setIdentity for row in 0...4 do for col in 0...4 do index = 4*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 1465 def setRow( v, row ) self[row,0] = v.x self[row,1] = v.y self[row,2] = v.z self[row,3] = v.w end
# File lib/rmath3d/rmath3d_plain.rb, line 1490 def setUpper3x3( mtx3x3 ) self.e00 = mtx3x3.e00 self.e01 = mtx3x3.e01 self.e02 = mtx3x3.e02 self.e10 = mtx3x3.e10 self.e11 = mtx3x3.e11 self.e12 = mtx3x3.e12 self.e20 = mtx3x3.e20 self.e21 = mtx3x3.e21 self.e22 = mtx3x3.e22 return self end
Clears all elements by 0.0
# File lib/rmath3d/rmath3d_plain.rb, line 1508 def setZero 16.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 2260 def sub!( other ) if ( other.class != RMtx4 ) raise TypeError, "RMtx4#sub! : Unknown type #{other.class} given as RMtx4." return nil end result = RMtx4.new for row in 0...4 do for col in 0...4 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 1316 def to_a return @e end
Returns human-readable string.
# File lib/rmath3d/rmath3d_plain.rb, line 1304 def to_s "( #{@e[0]}, #{@e[4]}, #{@e[8]}, #{@e[12]} )\n" + "( #{@e[1]}, #{@e[5]}, #{@e[9]}, #{@e[13]} )\n" + "( #{@e[2]}, #{@e[6]}, #{@e[10]}, #{@e[14]} )\n" + "( #{@e[3]}, #{@e[7]}, #{@e[11]}, #{@e[15]} )\n" end
Makes itself as a translation matrix.
# File lib/rmath3d/rmath3d_plain.rb, line 1686 def translation( tx, ty, tz ) setIdentity() self.e03 = tx self.e13 = ty self.e23 = tz return self end
Transposeas its elements.
# File lib/rmath3d/rmath3d_plain.rb, line 1570 def transpose! @e[ 1], @e[ 4] = @e[ 4], @e[ 1] @e[ 2], @e[ 8] = @e[ 8], @e[ 2] @e[ 3], @e[12] = @e[12], @e[ 3] @e[ 6], @e[ 9] = @e[ 9], @e[ 6] @e[ 7], @e[13] = @e[13], @e[ 7] @e[11], @e[14] = @e[14], @e[11] end
Private Instance Methods
# File lib/rmath3d/rmath3d_plain.rb, line 1534 def det3( _e00,_e01,_e02, _e10,_e11,_e12, _e20,_e21,_e22 ) _e00 * (_e11*_e22 - _e12*_e21) - _e01 * (_e10*_e22 - _e12*_e20) + _e02 * (_e10*_e21 - _e11*_e20) end