decompose2DMatrix static method

List decompose2DMatrix(
  1. Matrix4 matrix4
)

Implementation

static List decompose2DMatrix(Matrix4 matrix4) {

  List<double> m4storage = matrix4.storage;
  List<List<double>> matrix = [
    m4storage.sublist(0, 4),
    m4storage.sublist(4, 8),
    m4storage.sublist(8, 12),
    m4storage.sublist(12, 16)
  ];

  double row0x = matrix[0][0];
  double row0y = matrix[0][1];
  double row1x = matrix[1][0];
  double row1y = matrix[1][1];

  List<double> translate = List.filled(2, 0);
  translate[0] = matrix[3][0];
  translate[1] = matrix[3][1];

  // Compute scaling factors.
  List<double> scale = List.filled(2, 0); // [scaleX, scaleY]
  scale[0] = sqrt(row0x * row0x + row0y * row0y);
  scale[1] = sqrt(row1x * row1x + row1y * row1y);

  // If _determinant is negative, one axis was flipped.
  double _determinant = row0x * row1y - row0y * row1x;
  if (_determinant < 0) {
    // Flip axis with minimum unit vector _dot product.
    if (row0x < row1y)
      scale[0] = -scale[0];
    else
      scale[1] = -scale[1];
  }

  // Renormalize matrix to remove scale.
  if (scale[0] != 0) {
    row0x *= 1 / scale[0];
    row0y *= 1 / scale[0];
  }
  if (scale[1] != 0) {
    row1x *= 1 / scale[1];
    row1y *= 1 / scale[1];
  }

  // Compute rotation and renormalize matrix.
  double angle = atan2(row0y, row0x);

  if (angle != 0) {
    // Rotate(-angle) = [cos(angle), sin(angle), -sin(angle), cos(angle)]
    //                = [row0x, -row0y, row0y, row0x]
    // Thanks to the normalization above.
    double sn = -row0y;
    double cs = row0x;
    double m11 = row0x, m12 = row0y;
    double m21 = row1x, m22 = row1y;

    row0x = cs * m11 + sn * m21;
    row0y = cs * m12 + sn * m22;
    row1x = -sn * m11 + cs * m21;
    row1y = -sn * m12 + cs * m22;
  }

  double m11 = row0x;
  double m12 = row0y;
  double m21 = row1x;
  double m22 = row1y;

  // Convert into degrees because our rotation functions expect it.
  angle = _rad2deg(angle)!;

  return [translate, scale, angle, m11, m12, m21, m22];
}