Source: tiny/core/math/GroupD8.js

// Your friendly neighbour https://en.wikipedia.org/wiki/Dihedral_group of order 16
import Matrix from './Matrix';

const ux = [1, 1, 0, -1, -1, -1, 0, 1, 1, 1, 0, -1, -1, -1, 0, 1];
const uy = [0, 1, 1, 1, 0, -1, -1, -1, 0, 1, 1, 1, 0, -1, -1, -1];
const vx = [0, -1, -1, -1, 0, 1, 1, 1, 0, 1, 1, 1, 0, -1, -1, -1];
const vy = [1, 1, 0, -1, -1, -1, 0, 1, -1, -1, 0, 1, 1, 1, 0, -1];
const tempMatrices = [];

const mul = [];

function signum(x) {
  if (x < 0) {
    return -1;
  }
  if (x > 0) {
    return 1;
  }

  return 0;
}

function init() {
  for (let i = 0; i < 16; i++) {
    const row = [];

    mul.push(row);

    for (let j = 0; j < 16; j++) {
      const _ux = signum((ux[i] * ux[j]) + (vx[i] * uy[j]));
      const _uy = signum((uy[i] * ux[j]) + (vy[i] * uy[j]));
      const _vx = signum((ux[i] * vx[j]) + (vx[i] * vy[j]));
      const _vy = signum((uy[i] * vx[j]) + (vy[i] * vy[j]));

      for (let k = 0; k < 16; k++) {
        if (ux[k] === _ux && uy[k] === _uy && vx[k] === _vx && vy[k] === _vy) {
          row.push(k);
          break;
        }
      }
    }
  }

  for (let i = 0; i < 16; i++) {
    const mat = new Matrix();

    mat.set(ux[i], uy[i], vx[i], vy[i], 0, 0);
    tempMatrices.push(mat);
  }
}

init();

/**
 * Implements Dihedral Group D_8, see [group D4]{@link http://mathworld.wolfram.com/DihedralGroupD4.html}, D8 is the same but with diagonals. Used for texture rotations.
 *
 * Vector xX(i), xY(i) is U-axis of sprite with rotation i
 * Vector yY(i), yY(i) is V-axis of sprite with rotation i
 * Rotations: 0 grad (0), 90 grad (2), 180 grad (4), 270 grad (6)
 * Mirrors: vertical (8), main diagonal (10), horizontal (12), reverse diagonal (14)
 * This is the small part of gameofbombs.com portal system. It works.
 *
 * @author Ivan @ivanpopelyshev
 * @class
 * @memberof Tiny
 */
const GroupD8 = {
  E: 0,
  SE: 1,
  S: 2,
  SW: 3,
  W: 4,
  NW: 5,
  N: 6,
  NE: 7,
  MIRROR_VERTICAL: 8,
  MIRROR_HORIZONTAL: 12,
  uX: (ind) => ux[ind],
  uY: (ind) => uy[ind],
  vX: (ind) => vx[ind],
  vY: (ind) => vy[ind],
  inv: (rotation) => {
    if (rotation & 8) {
      return rotation & 15;
    }

    return (-rotation) & 7;
  },
  add: (rotationSecond, rotationFirst) => mul[rotationSecond][rotationFirst],
  sub: (rotationSecond, rotationFirst) => mul[rotationSecond][GroupD8.inv(rotationFirst)],

  /**
   * Adds 180 degrees to rotation. Commutative operation.
   *
   * @memberof Tiny.GroupD8
   * @param {number} rotation - The number to rotate.
   * @return {number} rotated number
   */
  rotate180: (rotation) => rotation ^ 4,

  /**
   * Direction of main vector can be horizontal, vertical or diagonal.
   * Some objects work with vertical directions different.
   *
   * @memberof Tiny.GroupD8
   * @version 1.2.0
   * @param {number} rotation - The number to check.
   * @return {boolean} Whether or not the direction is vertical
   */
  isVertical: (rotation) => (rotation & 3) === 2,

  /**
   * @memberof Tiny.GroupD8
   * @param {number} dx - TODO
   * @param {number} dy - TODO
   *
   * @return {number} TODO
   */
  byDirection: (dx, dy) => {
    if (Math.abs(dx) * 2 <= Math.abs(dy)) {
      if (dy >= 0) {
        return GroupD8.S;
      }

      return GroupD8.N;
    } else if (Math.abs(dy) * 2 <= Math.abs(dx)) {
      if (dx > 0) {
        return GroupD8.E;
      }

      return GroupD8.W;
    } else if (dy > 0) {
      if (dx > 0) {
        return GroupD8.SE;
      }

      return GroupD8.SW;
    } else if (dx > 0) {
      return GroupD8.NE;
    }

    return GroupD8.NW;
  },

  /**
   * Helps sprite to compensate texture packer rotation.
   *
   * @memberof Tiny.GroupD8
   * @param {Tiny.Matrix} matrix - sprite world matrix
   * @param {number} rotation - The rotation factor to use.
   * @param {number} tx - sprite anchoring
   * @param {number} ty - sprite anchoring
   */
  matrixAppendRotationInv: (matrix, rotation, tx = 0, ty = 0) => {
    // Packer used "rotation", we use "inv(rotation)"
    const mat = tempMatrices[GroupD8.inv(rotation)];

    mat.tx = tx;
    mat.ty = ty;
    matrix.append(mat);
  },
};

export default GroupD8;
Documentation generated by JSDoc 3.4.3 on Fri Jul 09 2021 19:32:25 GMT+0800 (CST)