/// <summary>
        /// Combines matrices by addition.
        /// </summary>
        public static TransformationMatrix2D operator +(TransformationMatrix2D matrix1, TransformationMatrix2D matrix2)
        {
            var result = new TransformationMatrix2D();

            for (int r = 0; r < 3; r++)
            {
                for (int c = 0; c < 3; c++)
                {
                    result[r, c] = matrix1[r, c] + matrix2[r, c];
                }
            }

            return(result);
        }
        /// <summary>
        /// Multiplies the matrix with a given factor.
        /// </summary>
        public static TransformationMatrix2D operator *(double factor, TransformationMatrix2D matrix)
        {
            var result = new TransformationMatrix2D();

            for (int r = 0; r < 3; r++)
            {
                for (int c = 0; c < 3; c++)
                {
                    result[r, c] = factor * matrix[r, c];
                }
            }

            return(result);
        }
        /// <summary>
        /// Returns a 2D transformation matrix for distorted scaling.
        /// </summary>
        public static TransformationMatrix2D Scaling(double sx, double sy)
        {
            var result = new TransformationMatrix2D();

            result[0, 0] = sx;
            result[0, 1] = 0;
            result[0, 2] = 0;
            result[1, 0] = 0;
            result[1, 1] = sy;
            result[1, 2] = 0;
            result[2, 0] = 0;
            result[2, 1] = 0;
            result[2, 2] = 1;
            return(result);
        }
        /// <summary>
        /// Returns a 2D transformation matrix for translating (displacing).
        /// </summary>
        public static TransformationMatrix2D Translating(double x, double y)
        {
            var result = new TransformationMatrix2D();

            result[0, 0] = 1;
            result[0, 1] = 0;
            result[0, 2] = x;
            result[1, 0] = 0;
            result[1, 1] = 1;
            result[1, 2] = y;
            result[2, 0] = 0;
            result[2, 1] = 0;
            result[2, 2] = 1;
            return(result);
        }
        /// <summary>
        /// Returns an identity 2D transformation matrix.
        /// </summary>
        public static TransformationMatrix2D Identity()
        {
            var result = new TransformationMatrix2D();

            result[0, 0] = 1;
            result[0, 1] = 0;
            result[0, 2] = 0;
            result[1, 0] = 0;
            result[1, 1] = 1;
            result[1, 2] = 0;
            result[2, 0] = 0;
            result[2, 1] = 0;
            result[2, 2] = 1;
            return(result);
        }
        /// <summary>
        /// Returns a 2D transformation matrix for rotation given the angle in radians.
        /// </summary>
        public static TransformationMatrix2D Rotating(double rad)
        {
            var result = new TransformationMatrix2D();

            result[0, 0] = Math.Cos(rad);
            result[0, 1] = -Math.Sin(rad);
            result[0, 2] = 0;
            result[1, 0] = Math.Sin(rad);
            result[1, 1] = Math.Cos(rad);
            result[1, 2] = 0;
            result[2, 0] = 0;
            result[2, 1] = 0;
            result[2, 2] = 1;
            return(result);
        }
        /// <summary>
        /// Combines matrices by multiplication.
        /// </summary>
        public static TransformationMatrix2D operator *(TransformationMatrix2D matrix1, TransformationMatrix2D matrix2)
        {
            var result = new TransformationMatrix2D();

            for (int r = 0; r < 3; r++)
            {
                for (int c = 0; c < 3; c++)
                {
                    for (int m = 0; m < 3; m++)
                    {
                        result[r, c] += matrix1[r, m] * matrix2[m, c];
                    }
                }
            }

            return(result);
        }