package openmods.geometry;
import com.google.common.base.Objects;
public class Matrix2d {
public double m00;
public double m01;
public double m10;
public double m11;
public Matrix2d() {}
public Matrix2d(Matrix2d src) {
copy(src);
}
public Matrix2d(double m00, double m10, double m01, double m11) {
this.m00 = m00;
this.m01 = m01;
this.m10 = m10;
this.m11 = m11;
}
public Matrix2d copy() {
return new Matrix2d(this);
}
public Matrix2d copy(Matrix2d src) {
return copy(src, this);
}
public static Matrix2d copy(Matrix2d src, Matrix2d dest) {
if (dest == null) dest = new Matrix2d();
dest.m00 = src.m00;
dest.m01 = src.m01;
dest.m10 = src.m10;
dest.m11 = src.m11;
return dest;
}
public static Matrix2d createIdentity() {
return new Matrix2d(+1, 0, 0, +1);
}
public static Matrix2d createSwap() {
return new Matrix2d(0, +1, +1, 0);
}
public static Matrix2d createRotateCW() {
return new Matrix2d(0, +1, -1, 0);
}
public static Matrix2d createRotateCCW() {
return new Matrix2d(0, -1, +1, 0);
}
public static Matrix2d createMirrorX() {
return new Matrix2d(-1, 0, 0, +1);
}
public static Matrix2d createMirrorY() {
return new Matrix2d(+1, 0, 0, -1);
}
public static Matrix2d createMirrorXY() {
return new Matrix2d(-1, 0, 0, -1);
}
public static Matrix2d add(Matrix2d left, Matrix2d right) {
return add(left, right, new Matrix2d());
}
public Matrix2d add(Matrix2d v) {
return add(v, this, this);
}
public static Matrix2d add(Matrix2d left, Matrix2d right, Matrix2d dest) {
dest.m00 = left.m00 + right.m00;
dest.m01 = left.m01 + right.m01;
dest.m10 = left.m10 + right.m10;
dest.m11 = left.m11 + right.m11;
return dest;
}
public static Matrix2d sub(Matrix2d left, Matrix2d right) {
return sub(left, right, new Matrix2d());
}
public Matrix2d sub(Matrix2d v) {
return sub(v, this, this);
}
public static Matrix2d sub(Matrix2d left, Matrix2d right, Matrix2d dest) {
dest.m00 = left.m00 - right.m00;
dest.m01 = left.m01 - right.m01;
dest.m10 = left.m10 - right.m10;
dest.m11 = left.m11 - right.m11;
return dest;
}
public static Matrix2d mul(Matrix2d left, Matrix2d right) {
return mul(left, right, new Matrix2d());
}
public Matrix2d mulLeft(Matrix2d v) {
return mul(v, this, this);
}
public Matrix2d mulRight(Matrix2d v) {
return mul(this, v, this);
}
public static Matrix2d mul(Matrix2d left, Matrix2d right, Matrix2d dest) {
final double m00 = left.m00 * right.m00 + left.m10 * right.m01;
final double m01 = left.m01 * right.m00 + left.m11 * right.m01;
final double m10 = left.m00 * right.m10 + left.m10 * right.m11;
final double m11 = left.m01 * right.m10 + left.m11 * right.m11;
dest.m00 = m00;
dest.m01 = m01;
dest.m10 = m10;
dest.m11 = m11;
return dest;
}
public double transformX(double x, double y) {
return m00 * x + m10 * y;
}
public double transformY(double x, double y) {
return m01 * x + m11 * y;
}
public Matrix2d transposeCopy() {
return transpose(new Matrix2d());
}
public Matrix2d transposeInplace() {
return transpose(this);
}
public Matrix2d transpose(Matrix2d dest) {
return transpose(this, dest);
}
public static Matrix2d transpose(Matrix2d src, Matrix2d dest) {
final double m01 = src.m10;
final double m10 = src.m01;
dest.m01 = m01;
dest.m10 = m10;
return dest;
}
public Matrix2d invertCopy() {
return invert(this, new Matrix2d());
}
public Matrix2d invertInplace() {
return invert(this, this);
}
public static Matrix2d invert(Matrix2d src) {
return invert(src, new Matrix2d());
}
public static Matrix2d invert(Matrix2d src, Matrix2d dest) {
double determinant = src.determinant();
if (determinant == 0) throw new ArithmeticException("Can't invert matrix " + src);
final double determinant_inv = 1f / determinant;
final double t00 = src.m11 * determinant_inv;
final double t01 = -src.m01 * determinant_inv;
final double t11 = src.m00 * determinant_inv;
final double t10 = -src.m10 * determinant_inv;
dest.m00 = t00;
dest.m01 = t01;
dest.m10 = t10;
dest.m11 = t11;
return dest;
}
@Override
public String toString() {
return "[" + m00 + ' ' + m10 + ';' + m01 + ' ' + m11 + ']';
}
public Matrix2d negate() {
return negate(this);
}
public Matrix2d negate(Matrix2d dest) {
return negate(this, dest);
}
public static Matrix2d negate(Matrix2d src, Matrix2d dest) {
dest.m00 = -src.m00;
dest.m01 = -src.m01;
dest.m10 = -src.m10;
dest.m11 = -src.m11;
return dest;
}
public Matrix2d setIdentity() {
return setIdentity(this);
}
public static Matrix2d setIdentity(Matrix2d src) {
src.m00 = 1.0;
src.m01 = 0.0;
src.m10 = 0.0;
src.m11 = 1.0;
return src;
}
public Matrix2d setZero() {
return setZero(this);
}
public static Matrix2d setZero(Matrix2d src) {
src.m00 = 0.0;
src.m01 = 0.0;
src.m10 = 0.0;
src.m11 = 0.0;
return src;
}
public double determinant() {
return m00 * m11 - m01 * m10;
}
@Override
public int hashCode() {
return Objects.hashCode(m00, m01, m10, m11);
}
@Override
public boolean equals(Object obj) {
if (obj instanceof Matrix2d) {
final Matrix2d o = (Matrix2d)obj;
return m00 == o.m00 &&
m01 == o.m01 &&
m10 == o.m10 &&
m11 == o.m11;
}
return false;
}
}