fourPointsTransform.js 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. var LN2 = Math.log(2);
  2. function 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. }
  29. export 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. }