class RMath3D::RMtx4

Document-class: RMath3D::RMtx4 provies 4x4 matrix arithmetic.

Notice

Public Class Methods

new → ((1,0,0,0),(0,1,0,0),(0,0,1,0),(0,0,0,1)) click to toggle source
new(e) → ((e,e,e,e),(e,e,e,e),(e,e,e,e),(e,e,e,e))
new( other ) : Copy Constructor
new( e0, e1, ..., e15 ) → ((e0,e1,e2,e3),(e4,e5,e6,e7),(e8,e9,e10,e11),(e12,e13,e14,e15))

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

* click to toggle source

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
+ click to toggle source

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
+ click to toggle source

+mtx : Unary plus operator.

# File lib/rmath3d/rmath3d_plain.rb, line 2127
def +@
  return self
end
- click to toggle source

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
- click to toggle source

-mtx : Unary minus operator.

# File lib/rmath3d/rmath3d_plain.rb, line 2136
def -@
  return RMtx4.new( self * -1.0 )
end
== click to toggle source

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
[row,col] → value click to toggle source

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
[row,col]= value click to toggle source

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
add!( mtx2 ) click to toggle source

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
coerse(other) click to toggle source

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
e00() click to toggle source

Returns the element at row 0 and column 0.

# File lib/rmath3d/rmath3d_plain.rb, line 1377
def e00() getElement(0,0) end
e00=(value) click to toggle source

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
e01() click to toggle source

Returns the element at row 0 and column 1.

# File lib/rmath3d/rmath3d_plain.rb, line 1379
def e01() getElement(0,1) end
e01=(value) click to toggle source

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
e02() click to toggle source

Returns the element at row 0 and column 2.

# File lib/rmath3d/rmath3d_plain.rb, line 1381
def e02() getElement(0,2) end
e02=(value) click to toggle source

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
e03() click to toggle source

Returns the element at row 0 and column 3.

# File lib/rmath3d/rmath3d_plain.rb, line 1383
def e03() getElement(0,3) end
e03=(value) click to toggle source

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
e10() click to toggle source

Returns the element at row 1 and column 0.

# File lib/rmath3d/rmath3d_plain.rb, line 1385
def e10() getElement(1,0) end
e10=(value) click to toggle source

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
e11() click to toggle source

Returns the element at row 1 and column 1.

# File lib/rmath3d/rmath3d_plain.rb, line 1387
def e11() getElement(1,1) end
e11=(value) click to toggle source

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
e12() click to toggle source

Returns the element at row 1 and column 2.

# File lib/rmath3d/rmath3d_plain.rb, line 1389
def e12() getElement(1,2) end
e12=(value) click to toggle source

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
e13() click to toggle source

Returns the element at row 1 and column 3.

# File lib/rmath3d/rmath3d_plain.rb, line 1391
def e13() getElement(1,3) end
e13=(value) click to toggle source

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
e20() click to toggle source

Returns the element at row 2 and column 0.

# File lib/rmath3d/rmath3d_plain.rb, line 1393
def e20() getElement(2,0) end
e20=(value) click to toggle source

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
e21() click to toggle source

Returns the element at row 2 and column 1.

# File lib/rmath3d/rmath3d_plain.rb, line 1395
def e21() getElement(2,1) end
e21=(value) click to toggle source

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
e22() click to toggle source

Returns the element at row 2 and column 2.

# File lib/rmath3d/rmath3d_plain.rb, line 1397
def e22() getElement(2,2) end
e22=(value) click to toggle source

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
e23() click to toggle source

Returns the element at row 2 and column 3.

# File lib/rmath3d/rmath3d_plain.rb, line 1399
def e23() getElement(2,3) end
e23=(value) click to toggle source

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
e30() click to toggle source

Returns the element at row 3 and column 0.

# File lib/rmath3d/rmath3d_plain.rb, line 1401
def e30() getElement(3,0) end
e30=(value) click to toggle source

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
e31() click to toggle source

Returns the element at row 3 and column 1.

# File lib/rmath3d/rmath3d_plain.rb, line 1403
def e31() getElement(3,1) end
e31=(value) click to toggle source

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
e32() click to toggle source

Returns the element at row 3 and column 2.

# File lib/rmath3d/rmath3d_plain.rb, line 1405
def e32() getElement(3,2) end
e32=(value) click to toggle source

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
e33() click to toggle source

Returns the element at row 3 and column 3.

# File lib/rmath3d/rmath3d_plain.rb, line 1407
def e33() getElement(3,3) end
e33=(value) click to toggle source

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
getColumn(c) → RVec4 click to toggle source

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
getDeterminant → determinant click to toggle source

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
getInverse → inverse click to toggle source

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
getRow(r) → RVec4 click to toggle source

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
getTransposed click to toggle source

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
getUpper3x3() click to toggle source
# 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
invert! → self click to toggle source

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
lookAtLH(eye,at,up) → self click to toggle source

Builds a viewing matrix for a left-handed coordinate system from:

  • eye position (eye: RVec3)

  • a point looking at (at: RVec3)

  • up vector (up: RVec3)

# 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
lookAtRH(eye,at,up) → self click to toggle source

Builds a viewing matrix for a right-handed coordinate system from:

  • eye position (eye: RVec3)

  • a point looking at (at: RVec3)

  • up vector (up: RVec3)

# 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
mul!( mtx2 ) click to toggle source

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
orthoLH(width,height,znear,zfar) → self click to toggle source

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
orthoOffCenterLH(left,right,bottom,top,znear,zfar) → self click to toggle source

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
orthoOffCenterRH(left,right,bottom,top,znear,zfar) → self click to toggle source

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
orthoRH(width,height,znear,zfar) → self click to toggle source

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
perspectiveFovLH(fovy,aspect,znear,zfar,ndc_homogeneous) → self click to toggle source

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
perspectiveFovRH(fovy,aspect,znear,zfar,ndc_homogeneous) → self click to toggle source

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
perspectiveLH(width,height,znear,zfar,ndc_convention) → self click to toggle source

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
perspectiveOffCenterLH(left,right,bottom,top,znear,zfar) → self click to toggle source

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
perspectiveOffCenterRH(left,right,bottom,top,znear,zfar) → self click to toggle source

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
perspectiveRH(width,height,znear,zfar,ndc_convention) → self click to toggle source

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
rotationAxis(axis,radian) → self click to toggle source

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
rotationQuaternion(q) → self click to toggle source

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
rotationX(radian) → self click to toggle source

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
rotationY(radian) → self click to toggle source

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
rotationZ(radian) → self click to toggle source

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
scaling(sx,sy,sz) → self click to toggle source

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
setColumn(v,c) click to toggle source

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
setElements( e0, e1, ..., e15 ) click to toggle source

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
setIdentity click to toggle source

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
setRow(v,r) click to toggle source

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
setUpper3x3( mtx3x3 ) click to toggle source
# 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
setZero click to toggle source

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
sub!( mtx2 ) click to toggle source

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
to_a click to toggle source

Returns its elements as a new Array.

# File lib/rmath3d/rmath3d_plain.rb, line 1316
def to_a
  return @e
end
to_s click to toggle source

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
translation(tx,ty,tz) → self click to toggle source

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
transpose! click to toggle source

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

det3( _e00,_e01,_e02, _e10,_e11,_e12, _e20,_e21,_e22 ) click to toggle source
# 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