I need the code to calculate a 2D transformation matrix from scale, rotation, translate and skew components.
The code should work like this calculator: http://angrytools.com/css-generator/transform , I tried to understand the explantion below, but I am not good with math.
Here a sample code of the converter that I am trying to implement.
public class TransformationMatrix2D
{
public double A { get; set; }
public double B { get; set; }
public double C { get; set; }
public double D { get; set; }
public double TX { get; set; }
public double TY { get; set; }
}
public class TransformationMatrix2DCalculator
{
public (double X, double Y) Translate { get; set; }
public double Rotate { get; set; }
public (double X, double Y) Scale { get; set; }
public double Skew { get; set; }
private const double TransformDegrees = 180 / Math.PI;
public TransformationMatrix2DCalculator(double translateX = 0, double translateY = 0, double rotate = 0, double scaleX = 1, double scaleY = 1, double skew = 0)
{
Translate = (translateX, translateY);
Rotate = rotate;
Scale = (scaleX, scaleY);
Skew = skew;
}
public TransformationMatrix2D Matrix => null; //TODO: to be implemented
}
UPDATE
I found how to apply rotation, translate and scale, but I don't know how to apply skew:
public TransformationMatrix2D GetMatrix()
{
var angle = Rotate / TransformDegrees;
var a = Math.Cos(angle) * Scale.X;
var b = Math.Sin(angle) * Scale.X;
var c = -Math.Sin(angle) * Scale.Y;
var d = Math.Cos(angle) * Scale.Y;
//TODO: complete transformations (skew support is missing)
return new TransformationMatrix2D()
{
A = a,
B = b,
C = c,
D = d,
TX = Translate.X,
TY = Translate.Y
};
}
Transformations are combined by representing each of them as individual matrices and then multiplying them.
A shearing matrix, which controls skew, uses the b and c parameters to control the skew of the x and y dimensions respectively.
However after multiplication, all 6 of the 2d matrix elements may be affected by skew.
You need to define a multiplication method on your matrix class, such as:
public static void Mult(in Matrix3d left, in Matrix3d right, out Matrix3d result)
{
double leftM11 = left.Row0.X;
double leftM12 = left.Row0.Y;
double leftM13 = left.Row0.Z;
double leftM21 = left.Row1.X;
double leftM22 = left.Row1.Y;
double leftM23 = left.Row1.Z;
double leftM31 = left.Row2.X;
double leftM32 = left.Row2.Y;
double leftM33 = left.Row2.Z;
double rightM11 = right.Row0.X;
double rightM12 = right.Row0.Y;
double rightM13 = right.Row0.Z;
double rightM21 = right.Row1.X;
double rightM22 = right.Row1.Y;
double rightM23 = right.Row1.Z;
double rightM31 = right.Row2.X;
double rightM32 = right.Row2.Y;
double rightM33 = right.Row2.Z;
result.Row0.X = (leftM11 * rightM11) + (leftM12 * rightM21) + (leftM13 * rightM31);
result.Row0.Y = (leftM11 * rightM12) + (leftM12 * rightM22) + (leftM13 * rightM32);
result.Row0.Z = (leftM11 * rightM13) + (leftM12 * rightM23) + (leftM13 * rightM33);
result.Row1.X = (leftM21 * rightM11) + (leftM22 * rightM21) + (leftM23 * rightM31);
result.Row1.Y = (leftM21 * rightM12) + (leftM22 * rightM22) + (leftM23 * rightM32);
result.Row1.Z = (leftM21 * rightM13) + (leftM22 * rightM23) + (leftM23 * rightM33);
result.Row2.X = (leftM31 * rightM11) + (leftM32 * rightM21) + (leftM33 * rightM31);
result.Row2.Y = (leftM31 * rightM12) + (leftM32 * rightM22) + (leftM33 * rightM32);
result.Row2.Z = (leftM31 * rightM13) + (leftM32 * rightM23) + (leftM33 * rightM33);
}
From the OpenTK Matrix3d class
and define your compound transformation as a product of elemental transformations (eg rotation, translation, scale, and rotation).
Also read up on transformation matrices
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.