Skip to content

Instantly share code, notes, and snippets.

@anyuser
Last active March 4, 2024 15:39
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save anyuser/bf3b6b76937f778636771153d8ba4ff6 to your computer and use it in GitHub Desktop.
Save anyuser/bf3b6b76937f778636771153d8ba4ff6 to your computer and use it in GitHub Desktop.
2D Transformation matrices for use in Unity
using UnityEngine;
public struct Matrix3x3
{
// m#row#col
public float m00;
public float m01;
public float m02;
public float m10;
public float m11;
public float m12;
public float m20;
public float m21;
public float m22;
public Matrix3x3 (
float m00,
float m01,
float m02,
float m10,
float m11,
float m12,
float m20,
float m21,
float m22)
{
this.m00 = m00;
this.m01 = m01;
this.m02 = m02;
this.m10 = m10;
this.m11 = m11;
this.m12 = m12;
this.m20 = m20;
this.m21 = m21;
this.m22 = m22;
}
public Matrix3x3 (Matrix3x3 m)
{
m00 = m.m00;
m10 = m.m10;
m20 = m.m20;
m01 = m.m01;
m11 = m.m11;
m21 = m.m21;
m02 = m.m02;
m12 = m.m12;
m22 = m.m22;
}
public Matrix3x3(Matrix4x4 m)
{
m00 = m.m00;
m10 = m.m10;
m20 = m.m30;
m01 = m.m01;
m11 = m.m11;
m21 = m.m31;
m02 = m.m02;
m12 = m.m12;
m22 = m.m32;
}
public Matrix4x4 Convert4x4()
{
Matrix4x4 m = new Matrix4x4();
m.m00 = m00;
m.m10 = m10;
m.m30 = m20;
m.m01 = m01;
m.m11 = m11;
m.m31 = m21;
m.m02 = m02;
m.m12 = m12;
m.m32 = m22;
return m;
}
public static Matrix3x3 identity {
get {
Matrix3x3 matrix = new Matrix3x3 ();
matrix.m00 = 1;
matrix.m11 = 1;
matrix.m22 = 1;
return matrix;
}
}
public float GetDeterminant ()
{
return m00 * (m11 * m22 - m12 * m21)
- m01 * (m10 * m22 - m12 * m20)
+ m02 * (m10 * m21 - m11 * m20);
}
public Matrix3x3 Invert ()
{
float determinant = GetDeterminant ();
if (determinant == 0)
throw new UnityException ("Can't invert matrix with determinant 0");
float invdet = 1f / determinant;
Matrix3x3 m = new Matrix3x3 ();
m.m00 = (m11 * m22 - m21 * m12) * invdet;
m.m10 = (m20 * m12 - m10 * m22) * invdet;
m.m20 = (m10 * m21 - m20 * m11) * invdet;
m.m01 = (m21 * m02 - m01 * m22) * invdet;
m.m11 = (m00 * m22 - m20 * m02) * invdet;
m.m21 = (m20 * m01 - m00 * m21) * invdet;
m.m02 = (m01 * m12 - m11 * m02) * invdet;
m.m12 = (m10 * m02 - m00 * m12) * invdet;
m.m22 = (m00 * m11 - m10 * m01) * invdet;
return m;
}
public Matrix3x3 Transpose ()
{
Matrix3x3 matrix = new Matrix3x3 ();
matrix.m00 = m00;
matrix.m01 = m10;
matrix.m02 = m20;
matrix.m10 = m01;
matrix.m11 = m11;
matrix.m12 = m21;
matrix.m20 = m02;
matrix.m21 = m12;
matrix.m22 = m22;
return matrix;
}
public static Vector2 MultiplyVector2 (Matrix3x3 m1, Vector2 inVector)
{
Vector2 outVector = new Vector2 ();
outVector.x = m1.m00 * inVector.x + m1.m01 * inVector.y + m1.m02;
outVector.y = m1.m10 * inVector.x + m1.m11 * inVector.y + m1.m12;
return outVector;
}
public static Vector3 MultiplyVector3 (Matrix3x3 m1, Vector3 inVector)
{
Vector3 outVector = new Vector3 ();
outVector.x = m1.m00 * inVector.x + m1.m01 * inVector.y + m1.m02;
outVector.y = m1.m10 * inVector.x + m1.m11 * inVector.y + m1.m12;
outVector.z = inVector.z;
return outVector;
}
public static Matrix3x3 MultiplyMatrix3x3 (Matrix3x3 m1, Matrix3x3 m2)
{
Matrix3x3 m = new Matrix3x3 ();
m.m00 = m1.m00 * m2.m00 + m1.m10 * m2.m01 + m1.m20 * m2.m02;
m.m10 = m1.m00 * m2.m10 + m1.m10 * m2.m11 + m1.m20 * m2.m12;
m.m20 = m1.m00 * m2.m20 + m1.m10 * m2.m21 + m1.m20 * m2.m22;
m.m01 = m1.m01 * m2.m00 + m1.m11 * m2.m01 + m1.m21 * m2.m02;
m.m11 = m1.m01 * m2.m10 + m1.m11 * m2.m11 + m1.m21 * m2.m12;
m.m21 = m1.m01 * m2.m20 + m1.m11 * m2.m21 + m1.m21 * m2.m22;
m.m02 = m1.m02 * m2.m00 + m1.m12 * m2.m01 + m1.m22 * m2.m02;
m.m12 = m1.m02 * m2.m10 + m1.m12 * m2.m11 + m1.m22 * m2.m12;
m.m22 = m1.m02 * m2.m20 + m1.m12 * m2.m21 + m1.m22 * m2.m22;
return m;
}
public static Matrix3x3 operator * (Matrix3x3 m1, Matrix3x3 m2)
{
return Matrix3x3.MultiplyMatrix3x3 (m1, m2);
}
public static Vector3 operator * (Matrix3x3 m, Vector3 v)
{
return Matrix3x3.MultiplyVector3 (m, v);
}
public static Vector2 operator * (Matrix3x3 m, Vector2 v)
{
return Matrix3x3.MultiplyVector2 (m, v);
}
public override string ToString ()
{
float det = GetDeterminant ();
return string.Format ("[Matrix3x3: det={9} m00={0}, m01={1}, m02={2}, m10={3}, m11={4}, m12={5}, m20={6}, m21={7}, m22={8}]", m00, m10, m20, m01, m11, m21, m02, m12, m22, det);
}
}
using UnityEngine;
using System.Collections;
public static class Matrix3x3Helpers
{
public static Matrix3x3 CreateTranslation (Vector2 translation)
{
Matrix3x3 m = new Matrix3x3 ();
m.m00 = 1;
m.m11 = 1;
m.m22 = 1;
m.m02 = translation.x;
m.m12 = translation.y;
return m;
}
public static Matrix3x3 CreateRotation (float rotation)
{
float cos = Mathf.Cos (rotation * Mathf.Deg2Rad);
float sin = Mathf.Sin (rotation * Mathf.Deg2Rad);
Matrix3x3 m = new Matrix3x3 ();
m.m00 = cos;
m.m01 = -sin;
m.m10 = sin;
m.m11 = cos;
m.m22 = 1;
return m;
}
public static Matrix3x3 CreateScale (Vector2 scale)
{
Matrix3x3 m = new Matrix3x3 ();
m.m00 = scale.x;
m.m11 = scale.y;
m.m22 = 1;
return m;
}
public static Matrix3x3 CreateTRS (Vector2 translation, float rotation, Vector2 scale)
{
float cos = Mathf.Cos (rotation * Mathf.Deg2Rad);
float sin = Mathf.Sin (rotation * Mathf.Deg2Rad);
Matrix3x3 m = new Matrix3x3 ();
m.m00 = scale.x * cos;
m.m01 = scale.y * -sin;
m.m02 = translation.x;
m.m10 = scale.x * sin;
m.m11 = scale.y * cos;
m.m12 = translation.y;
m.m20 = 0;
m.m21 = 0;
m.m22 = 1;
return m;
}
}
@eadgyo
Copy link

eadgyo commented Sep 5, 2018

If you want the same transformation behaviour as in Unity,
you must change this part in CreateTRS:
m.m01 = scale.x * -sin; by m.m01 = scale.y * -sin;
and
m.m10 = scale.y * sin; by m.m10 = scale.x * sin;

Otherwise, you would be applying the scaling after the rotation.

@dncstudyo
Copy link

+1

@anyuser
Copy link
Author

anyuser commented Mar 25, 2022

Thanks for the information, it's corrected now.

@Katadeus
Copy link

Katadeus commented Mar 4, 2024

Thank you very much!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment