简体   繁体   中英

Calculate transformation matrix from scale, rotation, translate and skew

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM