/// <summary> /// Multiplies all path segments in the specified list by the specified matrix. If there are any relative path segments in the /// list then they will be converted to their absolute counterparts. /// </summary> /// <param name="list">list of path segments to transform</param> /// <param name="matrix">matrix to multiply the path segment coordinates by</param> /// <returns>transformed list of path segments where all coordinates have been multiplied by the specified matrix</returns> public static SvgPathSegList MultiplyByMatrix(SvgPathSegList list, SvgMatrix matrix) { if (list == null) { throw new ArgumentNullException(nameof(list)); } if (matrix == null) { throw new ArgumentNullException(nameof(matrix)); } if (list.Any(i => RelativePathSegTypes.Contains(i.PathSegType))) { list = ConvertToAbsolute(list); } var transformer = new SvgPathSegMatrixTransformer(matrix); return(new SvgPathSegList(list.Select(item => item.Accept(transformer)))); }
/// <summary> /// Creates a rotation matrix about a given point. /// /// If optional parameters <see cref="x"/> and <see cref="y"/> are not supplied the operation corresponds to /// the matrix [cos(a) sin(a) -sin(a) cos(a) 0 0]. /// /// If optional parameters <see cref="x"/> and <see cref="y"/>, the rotate is about the point(x, y) and the operation /// represents the equivalent of the following specification: /// translate(x, y) rotate(angle) translate(-x, -y). /// </summary> public static SvgMatrix CreateRotate(float angleInDegrees, float?x = null, float?y = null) { if (x.HasValue != y.HasValue) { throw new ArgumentException(); } var radians = angleInDegrees * Math.PI / 180f; var cosA = (float)Math.Cos(radians); var sinA = (float)Math.Sin(radians); var rotMatrix = new SvgMatrix(cosA, sinA, -sinA, cosA, 0, 0); if (x != null) { var translate1 = CreateTranslate(x.Value, y.Value); var translate2 = CreateTranslate(-x.Value, -y.Value); return(Multiply(translate1, Multiply(rotMatrix, translate2))); } return(rotMatrix); }
private static SvgTransform CreateRotateTransformationFromArgs(string args) { // rotate(<rotate-angle> [<cx> <cy>]), which specifies a rotation by <rotate-angle> degrees about a given point. // // If optional parameters <cx> and <cy> are not supplied, the rotate is about the origin of the current user coordinate system. // The operation corresponds to the matrix [cos(a) sin(a) -sin(a) cos(a) 0 0]. // // If optional parameters<cx> and<cy> are supplied, the rotate is about the point(cx, cy). // The operation represents the equivalent of the following specification: // translate(< cx >, < cy >) rotate(< rotate - angle >) translate(-< cx >, -< cy >). var split = SplitStringOfNumbers(args); if (split.Length != 1 && split.Length != 3) { throw new Exception($"Invalid rotate transformation arguments '{args}'"); } var angle = float.Parse(split[0]); var cx = split.Length > 1 ? (float?)float.Parse(split[1]) : null; var cy = split.Length > 1 ? (float?)float.Parse(split[2]) : null; var matrix = SvgMatrix.CreateRotate(angle, cx, cy); return(new SvgTransform(SvgTransformType.Rotate, matrix, angle)); }
/// <summary> /// Multiplies all path segments in the specified list by the specified matrix. If there are any relative path segments in the /// list then they will be converted to their absolute counterparts. /// </summary> /// <param name="list">list of path segments to transform</param> /// <param name="matrix">matrix to multiply the path segment coordinates by</param> /// <returns>transformed list of path segments where all coordinates have been multiplied by the specified matrix</returns> public static SvgPathSegList MultiplyByMatrix(this SvgPathSegList list, SvgMatrix matrix) => SvgPathSegListTransformer.MultiplyByMatrix(list, matrix);
internal SvgTransform(SvgTransformType transformType, SvgMatrix matrix, float angle = 0) { Matrix = matrix ?? throw new ArgumentNullException(nameof(matrix)); TransformType = transformType; Angle = angle; }
public static void Multiply(SvgMatrix mat, float x, float y, out float resultX, out float resultY) { resultX = mat.A * x + mat.C * y + mat.E; resultY = mat.B * x + mat.D * y + mat.F; }