ADDED draw.html Index: draw.html ================================================================== --- draw.html +++ draw.html @@ -0,0 +1,1034 @@ + + + + + + + + ADDED matrix_vector_lib.js Index: matrix_vector_lib.js ================================================================== --- matrix_vector_lib.js +++ matrix_vector_lib.js @@ -0,0 +1,254 @@ + + +// matrix and vector functions. +// +// + +function vector_add(a, b, result){ + if(!result) result = []; + + if(a.length > b.lemgth){ + var tmp = a; + a = b; b = tmp; } + + for(var i = 0; i < a.length; ++i){ + result[i] = a[i] + b[i]; } + + for(var i = a.length; i < b.length; ++i){ + result[i] = b[i]; } + + return result; } + + +function vector_cpy(result, a){ + for(var i = 0; i < a.length; ++i){ + result[i] = a[i]; } +} + + + +function vector_minus(a, b, result){ + if(!result) result = []; + + var lim = Math.max(a.length, b.length); + + for(var i = 0; i < lim; ++i){ + var aValue, bValue; + if(i < a.length) + aValue = a[i]; + else + aValue = 0; + + if(i < b.length) + bValue = b[i]; + else + bValue = 0; + + result[i] = aValue - bValue; } + + + return result; } + + + +function vector_dot(a, b){ + var lim = Math.min(a.length, b.length); + var result = 0; + + for(var i = 0; i < lim; ++i){ + result += a[i] * b[i]; } + + return result; } + + +function vector_norm(a){ + return Math.sqrt(vector_dot(a,a)); } + + + + +function vector_scale(a, s, result){ + + if(!result) result = []; + + for(var i = 0; i < a.length; ++i){ + result[i] = s * a[i]; } + + return result; } + + + +// returns true iff the zero tail padded vectors match +function vector_cmp(a, b){ + + if(a.length > b.length){ + var tmp = a; + a = b; b = tmp; } + + for(var i = 0; i < a.length; ++i){ + if(a[i] != b[i]) + return false; } + + for(var i = a.length; i < b.length; ++i){ + if(b[i] != 0) + return false; } + + return true; } + + + +function midpoint(a, b, result){ + + if(b.length > a.length){ + var tmp = a; + a = b; b = tmp; } + + if(!result) result = new Array(b.length); + + for(var i = 0; i < a.length; ++i){ + result[i] = (a[i] + b[i])/2; } + + for(var i = a.length; i < b.length; ++i){ + result[i] = b[i]; } + + return result; +} + + + + +//this function may not care, but the expected matrix format in this project is a list of column vectors. +function matrix_transpose(matrix){ + + var result = []; + var dim0 = matrix.length; + if(!dim0) + return result; + + var dim1 = matrix[0].length; + + for(var i = 0; i < dim1; ++i){ + var colvector = []; + + for(var j = 0; j < dim0; ++j){ + colvector.push(matrix[j][i]); } + + result.push(colvector); } + + return result; } + + + + + + +function matrix_mult(a, b){ + + var result = []; + var a = matrix_transpose(a); + var dim0 = a.length; + var dim1 = b.length; + + for(var i = 0; i < dim1; ++i){ + var colvector = []; + + for(var j = 0; j < dim0; ++j){ + colvector.push( vector_dot(a[j], b[i]) ); } + result.push(colvector); } + + return result; } + + + +// finds the inverse of a 3 by 3 matrix, returns false if matrix has determinant zero. +// + +function matrix33inv(m){ + + // the matrix format is a list of column vectors. + var a = m[0][0]; + var b = m[1][0]; + var c = m[2][0]; + var d = m[0][1]; + var e = m[1][1]; + var f = m[2][1]; + var g = m[0][2]; + var h = m[1][2]; + var k = m[2][2]; + + // [ a b c + // d e f + // g h k ] + + + var A = e*k - f*h; + var B = f*g - d*k; + var C = d*h - e*g; + var D = h*c - b*k; + var E = a*k - c*g; + var F = g*b - a*h; + var G = b*f - e*c; + var H = d*c - a*f; + var K = a*e - d*b; + + + var det = (a*A + b*B + c*C); + + + if(det == 0) return false; + + // the multiplicative inverse of the determinant. + var di = 1/det; + + // the matrix format is a list of column vectors. + var result = [[di*A, di*B, di*C], + [di*D, di*E, di*F], + [di*G, di*H, di*K]]; + + return result; } + + +function compute_gradient(func, point, error){ + + if(!error) error = 0.00001; + + // find gradient + var otherpoint = point.slice(0); + var gradient = new Array(point.length); + var pointvalue = func(point); + + for(var i = 0; i < point.length; ++i){ + otherpoint[i] += error; + var othervalue = func(otherpoint) + gradient[i] = (othervalue - pointvalue) / error; + + otherpoint[i] -= error; } + + return gradient; +} + + + + +// +// equation at: +// http://inside.mines.edu/~gmurray/ArbitraryAxisRotation/ArbitraryAxisRotation.html +// creates a rotation matrix about the given vector. +// +function vector_rotation(vector, s){ + + var len = Math.sqrt(vector[0]*vector[0] + + vector[1]*vector[1] + + vector[2]*vector[2]); + + var u = vector[0]/len; + var v = vector[1]/len; + var w = vector[2]/len; + + var _cos = Math.cos(s); + var _sin = Math.sin(s); + var _1mcos = 1 - _cos; + + return [[u*u*_1mcos + _cos, u*v*_1mcos - w*_sin, u*w*_1mcos + v*_sin], + [u*v*_1mcos + w*_sin, v*v*_1mcos + _cos, v*w*_1mcos - u*_sin], + [u*w*_1mcos - v*_sin, v*w*_1mcos + u*_sin, w*w*_1mcos + _cos]]; }