Skip to content

Instantly share code, notes, and snippets.

@anyuser
Last active March 4, 2024 15:39
Show Gist options
  • Select an option

  • Save anyuser/bf3b6b76937f778636771153d8ba4ff6 to your computer and use it in GitHub Desktop.

Select an option

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

eadgyo commented Sep 5, 2018

Copy link
Copy Markdown

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
Copy Markdown

+1

@anyuser

anyuser commented Mar 25, 2022

Copy link
Copy Markdown
Author

Thanks for the information, it's corrected now.

@Katadeus

Katadeus commented Mar 4, 2024

Copy link
Copy Markdown

Thank you very much!

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