UNPKG

2.32 kBJavaScriptView Raw
1var LN2 = Math.log(2);
2function determinant(rows, rank, rowStart, rowMask, colMask, detCache) {
3 var cacheKey = rowMask + '-' + colMask;
4 var fullRank = rows.length;
5 if (detCache.hasOwnProperty(cacheKey)) {
6 return detCache[cacheKey];
7 }
8 if (rank === 1) {
9 var colStart = Math.round(Math.log(((1 << fullRank) - 1) & ~colMask) / LN2);
10 return rows[rowStart][colStart];
11 }
12 var subRowMask = rowMask | (1 << rowStart);
13 var subRowStart = rowStart + 1;
14 while (rowMask & (1 << subRowStart)) {
15 subRowStart++;
16 }
17 var sum = 0;
18 for (var j = 0, colLocalIdx = 0; j < fullRank; j++) {
19 var colTag = 1 << j;
20 if (!(colTag & colMask)) {
21 sum += (colLocalIdx % 2 ? -1 : 1) * rows[rowStart][j]
22 * determinant(rows, rank - 1, subRowStart, subRowMask, colMask | colTag, detCache);
23 colLocalIdx++;
24 }
25 }
26 detCache[cacheKey] = sum;
27 return sum;
28}
29export function buildTransformer(src, dest) {
30 var mA = [
31 [src[0], src[1], 1, 0, 0, 0, -dest[0] * src[0], -dest[0] * src[1]],
32 [0, 0, 0, src[0], src[1], 1, -dest[1] * src[0], -dest[1] * src[1]],
33 [src[2], src[3], 1, 0, 0, 0, -dest[2] * src[2], -dest[2] * src[3]],
34 [0, 0, 0, src[2], src[3], 1, -dest[3] * src[2], -dest[3] * src[3]],
35 [src[4], src[5], 1, 0, 0, 0, -dest[4] * src[4], -dest[4] * src[5]],
36 [0, 0, 0, src[4], src[5], 1, -dest[5] * src[4], -dest[5] * src[5]],
37 [src[6], src[7], 1, 0, 0, 0, -dest[6] * src[6], -dest[6] * src[7]],
38 [0, 0, 0, src[6], src[7], 1, -dest[7] * src[6], -dest[7] * src[7]]
39 ];
40 var detCache = {};
41 var det = determinant(mA, 8, 0, 0, 0, detCache);
42 if (det === 0) {
43 return;
44 }
45 var vh = [];
46 for (var i = 0; i < 8; i++) {
47 for (var j = 0; j < 8; j++) {
48 vh[j] == null && (vh[j] = 0);
49 vh[j] += ((i + j) % 2 ? -1 : 1)
50 * determinant(mA, 7, i === 0 ? 1 : 0, 1 << i, 1 << j, detCache)
51 / det * dest[i];
52 }
53 }
54 return function (out, srcPointX, srcPointY) {
55 var pk = srcPointX * vh[6] + srcPointY * vh[7] + 1;
56 out[0] = (srcPointX * vh[0] + srcPointY * vh[1] + vh[2]) / pk;
57 out[1] = (srcPointX * vh[3] + srcPointY * vh[4] + vh[5]) / pk;
58 };
59}