Published
Edited
Oct 25, 2020
Importers
1 star
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
a = mat3.create()
Insert cell
Insert cell
b = mat3create()
Insert cell
Insert cell
mat3 = ({
adjoint: mat3adjoint,
clone: mat3clone,
copy: mat3copy,
create: mat3create,
determinant: mat3determinant,
frob: mat3frob,
fromMat2d: mat3fromMat2d,
fromMat4: mat3fromMat4,
fromQuat: mat3fromQuat,
identity: mat3identity,
invert: mat3invert,
multiply: mat3multiply,
normalFromMat4: mat3normalFromMat4,
ortho: mat3ortho,
rotate: mat3rotate,
scale: mat3scale,
str: mat3str,
translate: mat3translate,
transpose: mat3transpose
})
Insert cell
/**
* Calculates the adjugate of a mat3
*
* @alias mat3.adjoint
* @param {mat3} out the receiving matrix
* @param {mat3} a the source matrix
* @returns {mat3} out
*/
function mat3adjoint(out, a) {
var a00 = a[0], a01 = a[1], a02 = a[2]
var a10 = a[3], a11 = a[4], a12 = a[5]
var a20 = a[6], a21 = a[7], a22 = a[8]

out[0] = (a11 * a22 - a12 * a21)
out[1] = (a02 * a21 - a01 * a22)
out[2] = (a01 * a12 - a02 * a11)
out[3] = (a12 * a20 - a10 * a22)
out[4] = (a00 * a22 - a02 * a20)
out[5] = (a02 * a10 - a00 * a12)
out[6] = (a10 * a21 - a11 * a20)
out[7] = (a01 * a20 - a00 * a21)
out[8] = (a00 * a11 - a01 * a10)

return out
}
Insert cell
/**
* Creates a new mat3 initialized with values from an existing matrix
*
* @alias mat3.clone
* @param {mat3} a matrix to clone
* @returns {mat3} a new 3x3 matrix
*/
function mat3clone(a) {
var out = new Float32Array(9)
out[0] = a[0]
out[1] = a[1]
out[2] = a[2]
out[3] = a[3]
out[4] = a[4]
out[5] = a[5]
out[6] = a[6]
out[7] = a[7]
out[8] = a[8]
return out
}
Insert cell
/**
* Copy the values from one mat3 to another
*
* @alias mat3.copy
* @param {mat3} out the receiving matrix
* @param {mat3} a the source matrix
* @returns {mat3} out
*/
function mat3copy(out, a) {
out[0] = a[0]
out[1] = a[1]
out[2] = a[2]
out[3] = a[3]
out[4] = a[4]
out[5] = a[5]
out[6] = a[6]
out[7] = a[7]
out[8] = a[8]
return out
}
Insert cell
/**
* Creates a new identity mat3
*
* @alias mat3.create
* @returns {mat3} a new 3x3 matrix
*/
function mat3create() {
var out = new Float32Array(9)
out[0] = 1
out[1] = 0
out[2] = 0
out[3] = 0
out[4] = 1
out[5] = 0
out[6] = 0
out[7] = 0
out[8] = 1
return out
}
Insert cell
/**
* Calculates the determinant of a mat3
*
* @alias mat3.determinant
* @param {mat3} a the source matrix
* @returns {Number} determinant of a
*/
function mat3determinant(a) {
var a00 = a[0], a01 = a[1], a02 = a[2]
var a10 = a[3], a11 = a[4], a12 = a[5]
var a20 = a[6], a21 = a[7], a22 = a[8]

return a00 * (a22 * a11 - a12 * a21)
+ a01 * (a12 * a20 - a22 * a10)
+ a02 * (a21 * a10 - a11 * a20)
}
Insert cell
/**
* Returns Frobenius norm of a mat3
*
* @alias mat3.frob
* @param {mat3} a the matrix to calculate Frobenius norm of
* @returns {Number} Frobenius norm
*/
function mat3frob(a) {
return Math.sqrt(
a[0]*a[0]
+ a[1]*a[1]
+ a[2]*a[2]
+ a[3]*a[3]
+ a[4]*a[4]
+ a[5]*a[5]
+ a[6]*a[6]
+ a[7]*a[7]
+ a[8]*a[8]
)
}
Insert cell
/**
* Copies the values from a mat2d into a mat3
*
* @alias mat3.fromMat2d
* @param {mat3} out the receiving matrix
* @param {mat2d} a the matrix to copy
* @returns {mat3} out
**/
function mat3fromMat2d(out, a) {
out[0] = a[0]
out[1] = a[1]
out[2] = 0

out[3] = a[2]
out[4] = a[3]
out[5] = 0

out[6] = a[4]
out[7] = a[5]
out[8] = 1

return out
}
Insert cell
/**
* Copies the upper-left 3x3 values into the given mat3.
*
* @alias mat3.fromMat4
* @param {mat3} out the receiving 3x3 matrix
* @param {mat4} a the source 4x4 matrix
* @returns {mat3} out
*/
function mat3fromMat4(out, a) {
out[0] = a[0]
out[1] = a[1]
out[2] = a[2]
out[3] = a[4]
out[4] = a[5]
out[5] = a[6]
out[6] = a[8]
out[7] = a[9]
out[8] = a[10]
return out
}
Insert cell
/**
* Calculates a 3x3 matrix from the given quaternion
*
* @alias mat3.fromQuat
* @param {mat3} out mat3 receiving operation result
* @param {quat} q Quaternion to create matrix from
*
* @returns {mat3} out
*/
function mat3fromQuat(out, q) {
var x = q[0]
var y = q[1]
var z = q[2]
var w = q[3]

var x2 = x + x
var y2 = y + y
var z2 = z + z

var xx = x * x2
var yx = y * x2
var yy = y * y2
var zx = z * x2
var zy = z * y2
var zz = z * z2
var wx = w * x2
var wy = w * y2
var wz = w * z2

out[0] = 1 - yy - zz
out[3] = yx - wz
out[6] = zx + wy

out[1] = yx + wz
out[4] = 1 - xx - zz
out[7] = zy - wx

out[2] = zx - wy
out[5] = zy + wx
out[8] = 1 - xx - yy

return out
}
Insert cell
/**
* Set a mat3 to the identity matrix
*
* @alias mat3.identity
* @param {mat3} out the receiving matrix
* @returns {mat3} out
*/
function mat3identity(out) {
out[0] = 1
out[1] = 0
out[2] = 0
out[3] = 0
out[4] = 1
out[5] = 0
out[6] = 0
out[7] = 0
out[8] = 1
return out
}
Insert cell
/**
* Inverts a mat3
*
* @alias mat3.invert
* @param {mat3} out the receiving matrix
* @param {mat3} a the source matrix
* @returns {mat3} out
*/
function mat3invert(out, a) {
var a00 = a[0], a01 = a[1], a02 = a[2]
var a10 = a[3], a11 = a[4], a12 = a[5]
var a20 = a[6], a21 = a[7], a22 = a[8]

var b01 = a22 * a11 - a12 * a21
var b11 = -a22 * a10 + a12 * a20
var b21 = a21 * a10 - a11 * a20

// Calculate the determinant
var det = a00 * b01 + a01 * b11 + a02 * b21

if (!det) return null
det = 1.0 / det

out[0] = b01 * det
out[1] = (-a22 * a01 + a02 * a21) * det
out[2] = (a12 * a01 - a02 * a11) * det
out[3] = b11 * det
out[4] = (a22 * a00 - a02 * a20) * det
out[5] = (-a12 * a00 + a02 * a10) * det
out[6] = b21 * det
out[7] = (-a21 * a00 + a01 * a20) * det
out[8] = (a11 * a00 - a01 * a10) * det

return out
}
Insert cell
/**
* Multiplies two mat3's
*
* @alias mat3.multiply
* @param {mat3} out the receiving matrix
* @param {mat3} a the first operand
* @param {mat3} b the second operand
* @returns {mat3} out
*/
function mat3multiply(out, a, b) {
var a00 = a[0], a01 = a[1], a02 = a[2]
var a10 = a[3], a11 = a[4], a12 = a[5]
var a20 = a[6], a21 = a[7], a22 = a[8]

var b00 = b[0], b01 = b[1], b02 = b[2]
var b10 = b[3], b11 = b[4], b12 = b[5]
var b20 = b[6], b21 = b[7], b22 = b[8]

out[0] = b00 * a00 + b01 * a10 + b02 * a20
out[1] = b00 * a01 + b01 * a11 + b02 * a21
out[2] = b00 * a02 + b01 * a12 + b02 * a22

out[3] = b10 * a00 + b11 * a10 + b12 * a20
out[4] = b10 * a01 + b11 * a11 + b12 * a21
out[5] = b10 * a02 + b11 * a12 + b12 * a22

out[6] = b20 * a00 + b21 * a10 + b22 * a20
out[7] = b20 * a01 + b21 * a11 + b22 * a21
out[8] = b20 * a02 + b21 * a12 + b22 * a22

return out
}
Insert cell
/**
* Calculates a 3x3 normal matrix (transpose inverse) from the 4x4 matrix
*
* @alias mat3.normalFromMat4
* @param {mat3} out mat3 receiving operation result
* @param {mat4} a Mat4 to derive the normal matrix from
*
* @returns {mat3} out
*/
function mat3normalFromMat4(out, a) {
var a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3]
var a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7]
var a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11]
var a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15]

var b00 = a00 * a11 - a01 * a10
var b01 = a00 * a12 - a02 * a10
var b02 = a00 * a13 - a03 * a10
var b03 = a01 * a12 - a02 * a11
var b04 = a01 * a13 - a03 * a11
var b05 = a02 * a13 - a03 * a12
var b06 = a20 * a31 - a21 * a30
var b07 = a20 * a32 - a22 * a30
var b08 = a20 * a33 - a23 * a30
var b09 = a21 * a32 - a22 * a31
var b10 = a21 * a33 - a23 * a31
var b11 = a22 * a33 - a23 * a32

// Calculate the determinant
var det = b00 * b11
- b01 * b10
+ b02 * b09
+ b03 * b08
- b04 * b07
+ b05 * b06

if (!det) return null
det = 1.0 / det

out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det
out[1] = (a12 * b08 - a10 * b11 - a13 * b07) * det
out[2] = (a10 * b10 - a11 * b08 + a13 * b06) * det

out[3] = (a02 * b10 - a01 * b11 - a03 * b09) * det
out[4] = (a00 * b11 - a02 * b08 + a03 * b07) * det
out[5] = (a01 * b08 - a00 * b10 - a03 * b06) * det

out[6] = (a31 * b05 - a32 * b04 + a33 * b03) * det
out[7] = (a32 * b02 - a30 * b05 - a33 * b01) * det
out[8] = (a30 * b04 - a31 * b02 + a33 * b00) * det

return out
}
Insert cell
function mat3ortho(out, left, right, bottom, top) {
const lr = 1 / (left - right);
const bt = 1 / (bottom - top);
out[0] = -2 * lr;
out[1] = 0;
out[2] = 0;

out[3] = 0;
out[4] = -2 * bt;
out[5] = 0;

out[6] = (left + right) * lr;
out[7] = (top + bottom) * bt;
out[8] = 1;
return out;
}
Insert cell
/**
* Rotates a mat3 by the given angle
*
* @alias mat3.rotate
* @param {mat3} out the receiving matrix
* @param {mat3} a the matrix to rotate
* @param {Number} rad the angle to rotate the matrix by
* @returns {mat3} out
*/
function mat3rotate(out, a, rad) {
var a00 = a[0], a01 = a[1], a02 = a[2]
var a10 = a[3], a11 = a[4], a12 = a[5]
var a20 = a[6], a21 = a[7], a22 = a[8]

var s = Math.sin(rad)
var c = Math.cos(rad)

out[0] = c * a00 + s * a10
out[1] = c * a01 + s * a11
out[2] = c * a02 + s * a12

out[3] = c * a10 - s * a00
out[4] = c * a11 - s * a01
out[5] = c * a12 - s * a02

out[6] = a20
out[7] = a21
out[8] = a22

return out
}
Insert cell
/**
* Scales the mat3 by the dimensions in the given vec2
*
* @alias mat3.scale
* @param {mat3} out the receiving matrix
* @param {mat3} a the matrix to rotate
* @param {vec2} v the vec2 to scale the matrix by
* @returns {mat3} out
**/
function mat3scale(out, a, v) {
var x = v[0]
var y = v[1]

out[0] = x * a[0]
out[1] = x * a[1]
out[2] = x * a[2]

out[3] = y * a[3]
out[4] = y * a[4]
out[5] = y * a[5]

out[6] = a[6]
out[7] = a[7]
out[8] = a[8]

return out
}
Insert cell
/**
* Returns a string representation of a mat3
*
* @alias mat3.str
* @param {mat3} mat matrix to represent as a string
* @returns {String} string representation of the matrix
*/
function mat3str(a) {
return 'mat3(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' +
a[3] + ', ' + a[4] + ', ' + a[5] + ', ' +
a[6] + ', ' + a[7] + ', ' + a[8] + ')'
}
Insert cell
/**
* Translate a mat3 by the given vector
*
* @alias mat3.translate
* @param {mat3} out the receiving matrix
* @param {mat3} a the matrix to translate
* @param {vec2} v vector to translate by
* @returns {mat3} out
*/
function mat3translate(out, a, v) {
var a00 = a[0], a01 = a[1], a02 = a[2]
var a10 = a[3], a11 = a[4], a12 = a[5]
var a20 = a[6], a21 = a[7], a22 = a[8]
var x = v[0], y = v[1]

out[0] = a00
out[1] = a01
out[2] = a02

out[3] = a10
out[4] = a11
out[5] = a12

out[6] = x * a00 + y * a10 + a20
out[7] = x * a01 + y * a11 + a21
out[8] = x * a02 + y * a12 + a22

return out
}
Insert cell
/**
* Transpose the values of a mat3
*
* @alias mat3.transpose
* @param {mat3} out the receiving matrix
* @param {mat3} a the source matrix
* @returns {mat3} out
*/
function mat3transpose(out, a) {
// If we are transposing ourselves we can skip a few steps but have to cache some values
if (out === a) {
var a01 = a[1], a02 = a[2], a12 = a[5]
out[1] = a[3]
out[2] = a[6]
out[3] = a01
out[5] = a[7]
out[6] = a02
out[7] = a12
} else {
out[0] = a[0]
out[1] = a[3]
out[2] = a[6]
out[3] = a[1]
out[4] = a[4]
out[5] = a[7]
out[6] = a[2]
out[7] = a[5]
out[8] = a[8]
}

return out
}
Insert cell

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more