Affine transformations to Object

Hello.
I am trying to make an application to calculate the 2D affine transformation of an object, but not only the standard transformations (translation, rotation, scaling, etc), I want the user to be able to input any number in 9 text fields (a 3x3 matrix) and for the object to transform based on those numbers. The object is square shaped.
This is the formula I wil be using:

25828-affine.png

Where the matrix with the "a"s is my affine transformation matrix (where the user will be inputting) and the x and y have to be calculated for each of the four points that limit my square.
Now, my question is, to what values should I assign the position, rotation, and scaling properties of my Unity object, considering that those four points could be anywhere on my plane?
I am aware that this is a mathematical question more than a Game Development question; however I am using Unity for my application would like to know if someone can help me with this.
Thanks!

Okay so here is a Matrix3x3 class, you could quite easily add a lot more function for other things, but I think what I have done will suffice as a good start, so the main class:

using UnityEngine;
using System.Collections;

public class Matrix3x3{
	public static Matrix3x3 identity = new Matrix3x3(1, 0, 0, 0, 1, 0, 0, 0, 1);
	public static Matrix3x3 zero = new Matrix3x3(0, 0, 0, 0, 0, 0, 0, 0, 0);

	public float[,] matrix;
	
	public Matrix3x3(){
		matrix = new float[3, 3];
		matrix[0, 0] = 0;
		matrix[1, 0] = 0;
		matrix[2, 0] = 0;
		matrix[0, 1] = 0;
		matrix[1, 1] = 0;
		matrix[2, 1] = 0;
		matrix[0, 2] = 0;
		matrix[1, 2] = 0;
		matrix[2, 2] = 0;
	}
	public Matrix3x3(float a11, float a12, float a13, float a21, float a22, float a23){
		matrix = new float[3, 3];
		matrix[0, 0] = a11;
		matrix[1, 0] = a12;
		matrix[2, 0] = a13;
		matrix[0, 1] = a21;
		matrix[1, 1] = a22;
		matrix[2, 1] = a23;
		matrix[0, 2] = 0;
		matrix[1, 2] = 0;
		matrix[2, 2] = 1;
	}
	public Matrix3x3(Vector3 a1, Vector3 a2){
		matrix = new float[3, 3];
		matrix[0, 0] = a1.x;
		matrix[1, 0] = a1.y;
		matrix[2, 0] = a1.z;
		matrix[0, 1] = a2.x;
		matrix[1, 1] = a2.y;
		matrix[2, 1] = a2.z;
		matrix[0, 2] = 0;
		matrix[1, 2] = 0;
		matrix[2, 2] = 1;
	}
	public Matrix3x3(float a11, float a12, float a13, float a21, float a22, float a23, float a31, float a32, float a33){
		matrix = new float[3, 3];
		matrix[0, 0] = a11;
		matrix[1, 0] = a12;
		matrix[2, 0] = a13;
		matrix[0, 1] = a21;
		matrix[1, 1] = a22;
		matrix[2, 1] = a23;
		matrix[0, 2] = a31;
		matrix[1, 2] = a32;
		matrix[2, 2] = a33;
	}
	
	//MATRIX MULTIPLICATION
	public static Matrix3x3 operator *(Matrix3x3 m1, Matrix3x3 m2){
		float a11 = 
			m1.matrix[0, 0] * m2.matrix[0, 0] + 
			m1.matrix[1, 0] * m2.matrix[0, 1] +
			m1.matrix[2, 0] * m2.matrix[0, 2];
		float a12 = 
			m1.matrix[0, 0] * m2.matrix[1, 0] + 
			m1.matrix[1, 0] * m2.matrix[1, 1] +
			m1.matrix[2, 0] * m2.matrix[1, 2];
		float a13 = 
			m1.matrix[0, 0] * m2.matrix[2, 0] + 
			m1.matrix[1, 0] * m2.matrix[2, 1] +
			m1.matrix[2, 0] * m2.matrix[2, 2];
		float a21 = 
			m1.matrix[0, 1] * m2.matrix[0, 0] + 
			m1.matrix[1, 1] * m2.matrix[0, 1] +
			m1.matrix[2, 1] * m2.matrix[0, 2];
		float a22 = 
			m1.matrix[0, 1] * m2.matrix[1, 0] + 
			m1.matrix[1, 1] * m2.matrix[1, 1] +
			m1.matrix[2, 1] * m2.matrix[1, 2];
		float a23 = 
			m1.matrix[0, 1] * m2.matrix[2, 0] + 
			m1.matrix[1, 1] * m2.matrix[2, 1] +
			m1.matrix[2, 1] * m2.matrix[2, 2];
		float a31 = 
			m1.matrix[0, 2] * m2.matrix[0, 0] + 
			m1.matrix[1, 2] * m2.matrix[0, 1] +
			m1.matrix[2, 2] * m2.matrix[0, 2];
		float a32 = 
			m1.matrix[0, 2] * m2.matrix[1, 0] + 
			m1.matrix[1, 2] * m2.matrix[1, 1] +
			m1.matrix[2, 2] * m2.matrix[1, 2];
		float a33 = 
			m1.matrix[0, 2] * m2.matrix[2, 0] + 
			m1.matrix[1, 2] * m2.matrix[2, 1] +
			m1.matrix[2, 2] * m2.matrix[2, 2];
		return new Matrix3x3(a11, a12, a13, a21, a22, a23, a31, a32, a33);
	}
	
	//FLOAT MULTIPLICATION
	public static Matrix3x3 operator *(Matrix3x3 m, float f){
		for(int i = 0; i < 3; i++){
			for(int j = 0; j < 3; j++){
				m.matrix[i, j] *= f;
			}
		}
		return m;
	}
	public static Matrix3x3 operator *(float f, Matrix3x3 m){
		for(int i = 0; i < 3; i++){
			for(int j = 0; j < 3; j++){
				m.matrix[i, j] *= f;
			}
		}
		return m;
	}
	
	//ToSTRING OVERRIDE
	public override string ToString(){
		string str = "[";
		for(int i = 0; i < 3; i++){
			for(int j = 0; j < 3; j++){
				str += matrix[j, i].ToString();
				str += i*j == 4 ? "]" : ", ";
			}
		}
		return str;
	}
}

public static class ExtensionMethods{
	public static Vector3 MultiplyPoint(this Matrix3x3 m, Vector3 point){
		Vector3 newPoint;
		newPoint.x = m.matrix[0, 0]*point.x + m.matrix[1, 0]*point.y + m.matrix[2, 0];
		newPoint.y = m.matrix[0, 1]*point.x + m.matrix[1, 1]*point.y + m.matrix[2, 1];
		newPoint.z = point.z;
		return newPoint;
	}
	
	public static Vector3 MultiplyVector(this Matrix3x3 m, Vector3 vec){
		Vector3 newVec;
		newVec.x = m.matrix[0, 0]*vec.x + m.matrix[1, 0]*vec.y;
		newVec.y = m.matrix[0, 1]*vec.x + m.matrix[1, 1]*vec.y;
		newVec.z = vec.z;
		return newVec;
	}
	
	public static Matrix3x3 Transpose(this Matrix3x3 m){
		Matrix3x3 newM = new Matrix3x3();
		for(int i = 0; i < 3; i++){
			for(int j = 0; j < 3; j++){
				newM.matrix[i, j] = m.matrix[j, i];
			}
		}
		return newM;
	}
	
	public static Matrix3x3 Inverse(this Matrix3x3 m){
		Matrix3x3 newM;
		float a11 = m.matrix[0, 0];
		float a12 = m.matrix[1, 0];
		float a13 = m.matrix[2, 0];
		float a21 = m.matrix[0, 1];
		float a22 = m.matrix[1, 1];
		float a23 = m.matrix[2, 1];
		float a31 = m.matrix[0, 2];
		float a32 = m.matrix[1, 2];
		float a33 = m.matrix[2, 2];
		
		float m11 = (a22*a33)-(a23*a32);
		float m12 = (a21*a33)-(a23*a31);
		float m13 = (a21*a32)-(a22*a31);
		float m21 = (a12*a33)-(a13*a32);
		float m22 = (a11*a33)-(a13*a31);
		float m23 = (a11*a32)-(a12*a31);
		float m31 = (a12*a23)-(a13*a22);
		float m32 = (a11*a23)-(a13*a21);
		float m33 = (a11*a22)-(a12*a21);
		
		newM = new Matrix3x3(m11, -m12, m13, -m21, m22, -m23, m31, -m32, m33);
		newM = newM.Transpose();
		float detM = (m*newM).matrix[0, 0];
		if(detM == 0){
			Debug.Log("determinant is 0, no inverse could be found (original matrix has been returned)");
			return m;
		}else{
			detM = 1f/detM;
			newM = detM*newM;
			return newM;
		}
	}
}

So far I think I have covered creating a 3x3 matrix, invereses, identity, zero matrix, transposing a matrix, multiplying a point and multiplying a vector, as well as some quality of life stuff like operator overloads for easily multiplying matricies by matricies or floats. To get an idea of how to use, check out the following:

Matrix3x3 m;
Matrix3x3 iM;
Matrix3x3 tM;
Matrix3x3 newM;

public Vector3 point;
public Vector3 vector;

void Start(){
	m = new Matrix3x3(1, 2, 3, 1, 1, 1, 3, 7, 9);
	iM = m.Inverse();
	tM = m.Transpose();
	
	Debug.Log("matrix: " + m);
	Debug.Log("inverse of matrix: " + iM);
	Debug.Log("transpose of matrix: " + tM);
	Debug.Log("inverse times matrix: " + m*iM);
	Debug.Log("identity matrix: " + Matrix3x3.identity);
	Debug.Log("zero matrix: " + Matrix3x3.zero);
	
	m = new Matrix3x3(1, 0, 3, 0, 1, 12);
	point = new Vector3(1, 2, 3);
	Debug.Log("matrix: " + m);
	Debug.Log("point: " + point);
	point = m.MultiplyPoint(point);
	Debug.Log("transformed point: " + point);
	
	m = new Matrix3x3(new Vector3(2, 3, 4), new Vector3(12, 2, 1));
	vector = new Vector3(2, 1, 3);
	Debug.Log("matrix: " + m);
	Debug.Log("vector: " + vector);
	vector = m.MultiplyVector(vector);
	Debug.Log("transformed vector: " + vector);
	
	m = new Matrix3x3(1, 2, 3, 1, 1, 1, 3, 7, 9);
	Debug.Log("matrix: " + m);
	m *= 3;
	Debug.Log(" 3 x matrix: " + m);
}

I hope that helps,

Scribe

After much investigation and mathematical calculations I came upon the answer. I share it in case it is useful for someone else.
I excecuted 3 methods after assigning each of the four points’ coordineates using the aforementioned formula:

void calculateRotation()
{ 
	transform.rotation = (new Quaternion (0, 0, Mathf.Atan ((point1.y * point1Previous.x - point1.x * point1Previous.y) / (point1.x * point1Previous.x + point1.y * point1Previous.y)),0));
}

void  calculateScale()
{
	transform.localScale = (new Vector3 (Vector3.Distance (point1, point2) / distScale, Vector3.Distance (point1, point3) / distScale, 1));

}

void calculateTrans()
{

	transform.position = (new Vector3 (original.x + matrixFields [2], original.y + matrixFields [5],0));
}

My points are distributed the following way: point1 is in the upper left corner, point 2 on the upper right corner, 3 lower left and 4 lower right. distScale is a variable where I store the original distance between points 1 and 2 (assinged on Start, same for x and y because mine is a square object), original stores the original position of the parent object.

EDIT:
After a lot of testing this doesn’t work correctly. IT can’t handle skewing and it sometimes reflects and rotates the object wrong. Still open to solution.
Someone in the Forum suggested that I use Unity’s 4x4 Matrix. However, I don’t know how to do it.
Thanks!

Look at the source code for OpenCV getPerspectiveTransform.