UNPKG

mind-ar

Version:

web augmented reality framework

119 lines (104 loc) 3.73 kB
// check which side point C on the line from A to B const linePointSide = (A, B, C) => { return ((B[0]-A[0])*(C[1]-A[1])-(B[1]-A[1])*(C[0]-A[0])); } // srcPoints, dstPoints: array of four elements [x, y] const checkFourPointsConsistent = (x1, x2, x3, x4, x1p, x2p, x3p, x4p) => { if ((linePointSide(x1, x2, x3) > 0) !== (linePointSide(x1p, x2p, x3p) > 0)) return false; if ((linePointSide(x2, x3, x4) > 0) !== (linePointSide(x2p, x3p, x4p) > 0)) return false; if ((linePointSide(x3, x4, x1) > 0) !== (linePointSide(x3p, x4p, x1p) > 0)) return false; if ((linePointSide(x4, x1, x2) > 0) !== (linePointSide(x4p, x1p, x2p) > 0)) return false; return true; } const checkThreePointsConsistent = (x1, x2, x3, x1p, x2p, x3p) => { if ((linePointSide(x1, x2, x3) > 0) !== (linePointSide(x1p, x2p, x3p) > 0)) return false; return true; } const determinant = (A) => { const C1 = A[4] * A[8] - A[5] * A[7]; const C2 = A[3] * A[8] - A[5] * A[6]; const C3 = A[3] * A[7] - A[4] * A[6]; return A[0] * C1 - A[1] * C2 + A[2] * C3; } const matrixInverse33 = (A, threshold) => { const det = determinant(A); if (Math.abs(det) <= threshold) return null; const oneOver = 1.0 / det; const B = [ (A[4] * A[8] - A[5] * A[7]) * oneOver, (A[2] * A[7] - A[1] * A[8]) * oneOver, (A[1] * A[5] - A[2] * A[4]) * oneOver, (A[5] * A[6] - A[3] * A[8]) * oneOver, (A[0] * A[8] - A[2] * A[6]) * oneOver, (A[2] * A[3] - A[0] * A[5]) * oneOver, (A[3] * A[7] - A[4] * A[6]) * oneOver, (A[1] * A[6] - A[0] * A[7]) * oneOver, (A[0] * A[4] - A[1] * A[3]) * oneOver, ]; return B; } const matrixMul33 = (A, B) => { const C = []; C[0] = A[0]*B[0] + A[1]*B[3] + A[2]*B[6]; C[1] = A[0]*B[1] + A[1]*B[4] + A[2]*B[7]; C[2] = A[0]*B[2] + A[1]*B[5] + A[2]*B[8]; C[3] = A[3]*B[0] + A[4]*B[3] + A[5]*B[6]; C[4] = A[3]*B[1] + A[4]*B[4] + A[5]*B[7]; C[5] = A[3]*B[2] + A[4]*B[5] + A[5]*B[8]; C[6] = A[6]*B[0] + A[7]*B[3] + A[8]*B[6]; C[7] = A[6]*B[1] + A[7]*B[4] + A[8]*B[7]; C[8] = A[6]*B[2] + A[7]*B[5] + A[8]*B[8]; return C; } const multiplyPointHomographyInhomogenous = (x, H) => { const w = H[6]*x[0] + H[7]*x[1] + H[8]; const xp = []; xp[0] = (H[0]*x[0] + H[1]*x[1] + H[2])/w; xp[1] = (H[3]*x[0] + H[4]*x[1] + H[5])/w; return xp; } const smallestTriangleArea = (x1, x2, x3, x4) => { const v12 = _vector(x2, x1); const v13 = _vector(x3, x1); const v14 = _vector(x4, x1); const v32 = _vector(x2, x3); const v34 = _vector(x4, x3); const a1 = _areaOfTriangle(v12, v13); const a2 = _areaOfTriangle(v13, v14); const a3 = _areaOfTriangle(v12, v14); const a4 = _areaOfTriangle(v32, v34); return Math.min(Math.min(Math.min(a1, a2), a3), a4); } // check if four points form a convex quadrilaternal. // all four combinations should have same sign const quadrilateralConvex = (x1, x2, x3, x4) => { const first = linePointSide(x1, x2, x3) <= 0; if ( (linePointSide(x2, x3, x4) <= 0) !== first) return false; if ( (linePointSide(x3, x4, x1) <= 0) !== first) return false; if ( (linePointSide(x4, x1, x2) <= 0) !== first) return false; //if (linePointSide(x1, x2, x3) <= 0) return false; //if (linePointSide(x2, x3, x4) <= 0) return false; //if (linePointSide(x3, x4, x1) <= 0) return false; //if (linePointSide(x4, x1, x2) <= 0) return false; return true; } const _vector = (a, b) => { return [ a[0] - b[0], a[1] - b[1] ] } const _areaOfTriangle = (u, v) => { const a = u[0]*v[1] - u[1]*v[0]; return Math.abs(a) * 0.5; } export { matrixInverse33, matrixMul33, quadrilateralConvex, smallestTriangleArea, multiplyPointHomographyInhomogenous, checkThreePointsConsistent, checkFourPointsConsistent, determinant }