public void Translate(double offsetX, double offsetY) { // // / a b 0 \ / 1 0 0 \ / a b 0 \ // | c d 0 | * | 0 1 0 | = | c d 0 | // \ e f 1 / \ x y 1 / \ e+x f+y 1 / // // (where e = _offsetX and f == _offsetY) // if (_type == MatrixTypes.Identity) { SetMatrix(1, 0, 0, 1, offsetX, offsetY, MatrixTypes.Translation); } else if (_type == MatrixTypes.Unknown) { _offsetX += offsetX; _offsetY += offsetY; } else { _offsetX += offsetX; _offsetY += offsetY; _type |= MatrixTypes.Translation; } }
/// <summary> /// Create a different matrix depending of the input parameter. /// </summary> /// <param name="matrixType">Enumeration MatrixType - there are Big, Small and Medium matrix.</param> /// <returns>Returns a new instance of matrix.</returns> public IMatrix CreateMatrix(MatrixTypes matrixType) { var director = new MatrixDirector(); MatrixBuilder builder; switch (matrixType) { case MatrixTypes.SMALL: builder = new SmallMatrixBuilder(); break; case MatrixTypes.MEDIUM: builder = new MediumMatrixBuilder(); break; case MatrixTypes.BIG: builder = new BigMatrixBuilder(); break; default: builder = new SmallMatrixBuilder(); break; } director.Construct(builder); return(builder.GetMatrix()); }
void DeriveMatrixType() { _type = 0; if (!(_m21 == 0 && _m12 == 0)) { _type = MatrixTypes.Unknown; return; } if (!(_m11 == 1 && _m22 == 1)) { _type = MatrixTypes.Scaling; } if (!(_offsetX == 0 && _offsetY == 0)) { _type |= MatrixTypes.Translation; } if (0 == (_type & (MatrixTypes.Translation | MatrixTypes.Scaling))) { _type = MatrixTypes.Identity; } return; }
/// <summary> /// Create a different matrix depending of the input parameter. /// </summary> /// <param name="matrixType">Enumeration MatrixType - there are Big, Small and Medium matrix.</param> /// <returns>Returns a new instance of matrix.</returns> public IMatrix CreateMatrix(MatrixTypes matrixType) { var director = new MatrixDirector(); MatrixBuilder builder; switch (matrixType) { case MatrixTypes.SMALL: builder = new SmallMatrixBuilder(); break; case MatrixTypes.MEDIUM: builder = new MediumMatrixBuilder(); break; case MatrixTypes.BIG: builder = new BigMatrixBuilder(); break; default: builder = new SmallMatrixBuilder(); break; } director.Construct(builder); return builder.GetMatrix(); }
internal static void TransformRect(ref Xamarin.Forms.Rectangle rect, ref Matrix matrix) { if (rect.IsEmpty) { return; } MatrixTypes matrixType = matrix._type; if (matrixType == MatrixTypes.Identity) { return; } // Scaling if (0 != (matrixType & MatrixTypes.Scaling)) { rect.X *= matrix._m11; rect.Y *= matrix._m22; rect.Width *= matrix._m11; rect.Height *= matrix._m22; if (rect.Width < 0.0) { rect.X += rect.Width; rect.Width = -rect.Width; } if (rect.Height < 0.0) { rect.Y += rect.Height; rect.Height = -rect.Height; } } // Translation if (0 != (matrixType & MatrixTypes.Translation)) { // X rect.X += matrix._offsetX; // Y rect.X += matrix._offsetY; } if (matrixType == MatrixTypes.Unknown) { Point point0 = matrix.Transform(new Point(rect.Right, rect.Top)); Point point1 = matrix.Transform(new Point(rect.Right, rect.Top)); Point point2 = matrix.Transform(new Point(rect.Right, rect.Bottom)); Point point3 = matrix.Transform(new Point(rect.Left, rect.Bottom)); rect.X = Math.Min(Math.Min(point0.X, point1.X), Math.Min(point2.X, point3.X)); rect.Y = Math.Min(Math.Min(point0.Y, point1.Y), Math.Min(point2.Y, point3.Y)); rect.Width = Math.Max(Math.Max(point0.X, point1.X), Math.Max(point2.X, point3.X)) - rect.X; rect.Height = Math.Max(Math.Max(point0.Y, point1.Y), Math.Max(point2.Y, point3.Y)) - rect.Y; } }
public static ArrayList CustomMatrixes(MatrixTypes mtype) { ArrayList list = new ArrayList(); string type = mtype.ToString().ToLower(); foreach (string file in Directory.GetFiles(Calculate.StartupPath + "\\presets\\matrix\\" + type, ("*." + type))) { list.Add(Path.GetFileNameWithoutExtension(file)); } return list; }
private void SetMatrix(double m11, double m12, double m21, double m22, double offsetX, double offsetY, MatrixTypes type) { this._m11 = m11; this._m12 = m12; this._m21 = m21; this._m22 = m22; this._offsetX = offsetX; this._offsetY = offsetY; this._type = type; }
private void SetMatrix(double m11, double m12, double m21, double m22, double offsetX, double offsetY, MatrixTypes type) { _m11 = m11; _m12 = m12; _m21 = m21; _m22 = m22; _offsetX = offsetX; _offsetY = offsetY; _type = type; }
public static ArrayList CustomMatrixes(MatrixTypes mtype) { ArrayList list = new ArrayList(); string type = mtype.ToString().ToLower(); foreach (string file in Directory.GetFiles(Calculate.StartupPath + "\\presets\\matrix\\" + type, ("*." + type))) { list.Add(Path.GetFileNameWithoutExtension(file)); } return(list); }
public Matrix(double m11, double m12, double m21, double m22, double offsetX, double offsetY) { this._m11 = m11; this._m12 = m12; this._m21 = m21; this._m22 = m22; this._offsetX = offsetX; this._offsetY = offsetY; this._type = MatrixTypes.TRANSFORM_IS_UNKNOWN; this._padding = 0; this.DeriveMatrixType(); }
private void SetMatrix(Float m11, Float m12, Float m21, Float m22, Float offsetX, Float offsetY, MatrixTypes type) { this._m11 = m11; this._m12 = m12; this._m21 = m21; this._m22 = m22; this._offsetX = offsetX; this._offsetY = offsetY; this._type = type; }
public Matrix(double m11, double m12, double m21, double m22, double offsetX, double offsetY) { _m11 = m11; _m12 = m12; _m21 = m21; _m22 = m22; _offsetX = offsetX; _offsetY = offsetY; _type = MatrixTypes.Unknown; _padding = 0; DeriveMatrixType(); }
internal static void TransformRect(ref Rectangle rect, ref Matrix matrix) { if (rect.IsEmpty) { return; } MatrixTypes type = matrix._type; if (type == MatrixTypes.TRANSFORM_IS_IDENTITY) { return; } if ((type & MatrixTypes.TRANSFORM_IS_SCALING) != MatrixTypes.TRANSFORM_IS_IDENTITY) { rect._x *= matrix._m11; rect._y *= matrix._m22; rect._width *= matrix._m11; rect._height *= matrix._m22; if (rect._width < 0.0) { rect._x += rect._width; rect._width = -rect._width; } if (rect._height < 0.0) { rect._y += rect._height; rect._height = -rect._height; } } if ((type & MatrixTypes.TRANSFORM_IS_TRANSLATION) != MatrixTypes.TRANSFORM_IS_IDENTITY) { rect._x += matrix._offsetX; rect._y += matrix._offsetY; } if (type != MatrixTypes.TRANSFORM_IS_UNKNOWN) { return; } Point point1 = matrix.Transform(rect.TopLeft); Point point2 = matrix.Transform(rect.TopRight); Point point3 = matrix.Transform(rect.BottomRight); Point point4 = matrix.Transform(rect.BottomLeft); rect._x = Math.Min(Math.Min(point1.X, point2.X), Math.Min(point3.X, point4.X)); rect._y = Math.Min(Math.Min(point1.Y, point2.Y), Math.Min(point3.Y, point4.Y)); rect._width = Math.Max(Math.Max(point1.X, point2.X), Math.Max(point3.X, point4.X)) - rect._x; rect._height = Math.Max(Math.Max(point1.Y, point2.Y), Math.Max(point3.Y, point4.Y)) - rect._y; }
public void Translate(double offsetX, double offsetY) { if (this._type == MatrixTypes.TRANSFORM_IS_IDENTITY) { this.SetMatrix(1.0, 0.0, 0.0, 1.0, offsetX, offsetY, MatrixTypes.TRANSFORM_IS_TRANSLATION); } else if (this._type == MatrixTypes.TRANSFORM_IS_UNKNOWN) { this._offsetX = this._offsetX + offsetX; this._offsetY = this._offsetY + offsetY; } else { this._offsetX = this._offsetX + offsetX; this._offsetY = this._offsetY + offsetY; this._type = this._type | MatrixTypes.TRANSFORM_IS_TRANSLATION; } }
internal static void MultiplyMatrix(ref Matrix matrix1, ref Matrix matrix2) { const MatrixTypes types = MatrixTypes.TransformIsUnknown; const MatrixTypes types2 = MatrixTypes.TransformIsScaling | MatrixTypes.TransformIsTranslation; int thisCase = ((((int)types) << 4) | ((int)types2)); switch (thisCase) { case 0x22: matrix1.M11 *= matrix2.M11; matrix1.M22 *= matrix2.M22; return; case 0x23: matrix1.M11 *= matrix2.M11; matrix1.M22 *= matrix2.M22; matrix1.OffsetX = matrix2.OffsetX; matrix1.OffsetY = matrix2.OffsetY; return; case 0x24: case 0x34: case 0x42: case 0x43: case 0x44: matrix1 = new Matrix((matrix1.M11 * matrix2.M11) + (matrix1.M12 * matrix2.M21), (matrix1.M11 * matrix2.M12) + (matrix1.M12 * matrix2.M22), (matrix1.M21 * matrix2.M11) + (matrix1.M22 * matrix2.M21), (matrix1.M21 * matrix2.M12) + (matrix1.M22 * matrix2.M22), ((matrix1.OffsetX * matrix2.M11) + (matrix1.OffsetY * matrix2.M21)) + matrix2.OffsetX, ((matrix1.OffsetX * matrix2.M12) + (matrix1.OffsetY * matrix2.M22)) + matrix2.OffsetY); return; case 50: matrix1.M11 *= matrix2.M11; matrix1.M22 *= matrix2.M22; matrix1.OffsetX *= matrix2.M11; matrix1.OffsetY *= matrix2.M22; return; case 0x33: matrix1.M11 *= matrix2.M11; matrix1.M22 *= matrix2.M22; matrix1.OffsetX = (matrix2.M11 * matrix1.OffsetX) + matrix2.OffsetX; matrix1.OffsetY = (matrix2.M22 * matrix1.OffsetY) + matrix2.OffsetY; return; } }
public ITableMapper Parse(JobParser parser, ParseState state) { var source = state.TryGet <string>("Select", mainParameter: true) ?? "Pages"; var type = state.TryGet("Type", "CoOccurrence"); var name = state.TryGet("Name", source + type); var selector = Selectors.SelectFromName(source); Func <ProcessingScope, IEnumerable <Tuple <object, object> > > matrix; if (type.Equals("cooccurrence", StringComparison.InvariantCultureIgnoreCase)) { matrix = scope => MatrixTypes.CoOcurrence(selector(scope)); } else if (type.Equals("links", StringComparison.InvariantCultureIgnoreCase)) { matrix = scope => MatrixTypes.Links(selector(scope)); } else { throw state.AttributeError("Unkown matrix type '{0}'", type); } var facts = state.SelectMany("CommonFields").Select(parser.ParseFieldMapper).ToList(); if (state.Select("CommonFields") == null) { facts.Add(new SimpleFieldMapper("Count", s => 1, typeof(int), FieldType.Fact)); } return(new MatrixTableMapper(state.AffixName(name), matrix, postfix => state.Postfix(postfix).SelectMany("Fields", true).Select(parser.ParseFieldMapper).ToArray(), facts)); }
private void DeriveMatrixType() { this._type = MatrixTypes.TRANSFORM_IS_IDENTITY; if (this._m21 != 0.0 || this._m12 != 0.0) { this._type = MatrixTypes.TRANSFORM_IS_UNKNOWN; } else { if (this._m11 != 1.0 || this._m22 != 1.0) { this._type = MatrixTypes.TRANSFORM_IS_SCALING; } if (this._offsetX != 0.0 || this._offsetY != 0.0) { this._type = this._type | MatrixTypes.TRANSFORM_IS_TRANSLATION; } if ((this._type & (MatrixTypes.TRANSFORM_IS_TRANSLATION | MatrixTypes.TRANSFORM_IS_SCALING)) != MatrixTypes.TRANSFORM_IS_IDENTITY) { return; } this._type = MatrixTypes.TRANSFORM_IS_IDENTITY; } }
internal static void MultiplyMatrix(ref Matrix matrix1, ref Matrix matrix2) { MatrixTypes type1 = matrix1._type; MatrixTypes type2 = matrix2._type; if (type2 == MatrixTypes.TRANSFORM_IS_IDENTITY) { return; } if (type1 == MatrixTypes.TRANSFORM_IS_IDENTITY) { matrix1 = matrix2; } else if (type2 == MatrixTypes.TRANSFORM_IS_TRANSLATION) { matrix1._offsetX += matrix2._offsetX; matrix1._offsetY += matrix2._offsetY; if (type1 == MatrixTypes.TRANSFORM_IS_UNKNOWN) { return; } matrix1._type |= MatrixTypes.TRANSFORM_IS_TRANSLATION; } else if (type1 == MatrixTypes.TRANSFORM_IS_TRANSLATION) { double offsetX = matrix1._offsetX; double offsetY = matrix1._offsetY; matrix1 = matrix2; matrix1._offsetX = offsetX * matrix2._m11 + offsetY * matrix2._m21 + matrix2._offsetX; matrix1._offsetY = offsetX * matrix2._m12 + offsetY * matrix2._m22 + matrix2._offsetY; if (type2 == MatrixTypes.TRANSFORM_IS_UNKNOWN) { matrix1._type = MatrixTypes.TRANSFORM_IS_UNKNOWN; } else { matrix1._type = MatrixTypes.TRANSFORM_IS_TRANSLATION | MatrixTypes.TRANSFORM_IS_SCALING; } } else { switch ((MatrixTypes)((int)type1 << 4) | type2) { case (MatrixTypes)34: matrix1._m11 *= matrix2._m11; matrix1._m22 *= matrix2._m22; break; case (MatrixTypes)35: matrix1._m11 *= matrix2._m11; matrix1._m22 *= matrix2._m22; matrix1._offsetX = matrix2._offsetX; matrix1._offsetY = matrix2._offsetY; matrix1._type = MatrixTypes.TRANSFORM_IS_TRANSLATION | MatrixTypes.TRANSFORM_IS_SCALING; break; case (MatrixTypes)36: case (MatrixTypes)52: case (MatrixTypes)66: case (MatrixTypes)67: case (MatrixTypes)68: matrix1 = new Matrix(matrix1._m11 * matrix2._m11 + matrix1._m12 * matrix2._m21, matrix1._m11 * matrix2._m12 + matrix1._m12 * matrix2._m22, matrix1._m21 * matrix2._m11 + matrix1._m22 * matrix2._m21, matrix1._m21 * matrix2._m12 + matrix1._m22 * matrix2._m22, matrix1._offsetX * matrix2._m11 + matrix1._offsetY * matrix2._m21 + matrix2._offsetX, matrix1._offsetX * matrix2._m12 + matrix1._offsetY * matrix2._m22 + matrix2._offsetY); break; case (MatrixTypes)50: matrix1._m11 *= matrix2._m11; matrix1._m22 *= matrix2._m22; matrix1._offsetX *= matrix2._m11; matrix1._offsetY *= matrix2._m22; break; case (MatrixTypes)51: matrix1._m11 *= matrix2._m11; matrix1._m22 *= matrix2._m22; matrix1._offsetX = matrix2._m11 * matrix1._offsetX + matrix2._offsetX; matrix1._offsetY = matrix2._m22 * matrix1._offsetY + matrix2._offsetY; break; } } }
/// <summary> /// Multiplies two transformations, where the behavior is matrix1 *= matrix2. /// This code exists so that we can efficient combine matrices without copying /// the data around, since each matrix is 52 bytes. /// To reduce duplication and to ensure consistent behavior, this is the /// method which is used to implement Matrix * Matrix as well. /// </summary> internal static void MultiplyMatrix(ref Matrix matrix1, ref Matrix matrix2) { MatrixTypes type1 = matrix1._type; MatrixTypes type2 = matrix2._type; // Check for idents // If the second is ident, we can just return if (type2 == MatrixTypes.TRANSFORM_IS_IDENTITY) { return; } // If the first is ident, we can just copy the memory across. if (type1 == MatrixTypes.TRANSFORM_IS_IDENTITY) { matrix1 = matrix2; return; } // Optimize for translate case, where the second is a translate if (type2 == MatrixTypes.TRANSFORM_IS_TRANSLATION) { // 2 additions matrix1._offsetX += matrix2._offsetX; matrix1._offsetY += matrix2._offsetY; // If matrix 1 wasn't unknown we added a translation if (type1 != MatrixTypes.TRANSFORM_IS_UNKNOWN) { matrix1._type |= MatrixTypes.TRANSFORM_IS_TRANSLATION; } return; } // Check for the first value being a translate if (type1 == MatrixTypes.TRANSFORM_IS_TRANSLATION) { // Save off the old offsets double offsetX = matrix1._offsetX; double offsetY = matrix1._offsetY; // Copy the matrix matrix1 = matrix2; matrix1._offsetX = offsetX * matrix2._m11 + offsetY * matrix2._m21 + matrix2._offsetX; matrix1._offsetY = offsetX * matrix2._m12 + offsetY * matrix2._m22 + matrix2._offsetY; if (type2 == MatrixTypes.TRANSFORM_IS_UNKNOWN) { matrix1._type = MatrixTypes.TRANSFORM_IS_UNKNOWN; } else { matrix1._type = MatrixTypes.TRANSFORM_IS_SCALING | MatrixTypes.TRANSFORM_IS_TRANSLATION; } return; } // The following code combines the type of the transformations so that the high nibble // is "this"'s type, and the low nibble is mat's type. This allows for a switch rather // than nested switches. // trans1._type | trans2._type // 7 6 5 4 | 3 2 1 0 int combinedType = ((int)type1 << 4) | (int)type2; switch (combinedType) { case 34: // S * S // 2 multiplications matrix1._m11 *= matrix2._m11; matrix1._m22 *= matrix2._m22; return; case 35: // S * S|T matrix1._m11 *= matrix2._m11; matrix1._m22 *= matrix2._m22; matrix1._offsetX = matrix2._offsetX; matrix1._offsetY = matrix2._offsetY; // Transform set to Translate and Scale matrix1._type = MatrixTypes.TRANSFORM_IS_TRANSLATION | MatrixTypes.TRANSFORM_IS_SCALING; return; case 50: // S|T * S matrix1._m11 *= matrix2._m11; matrix1._m22 *= matrix2._m22; matrix1._offsetX *= matrix2._m11; matrix1._offsetY *= matrix2._m22; return; case 51: // S|T * S|T matrix1._m11 *= matrix2._m11; matrix1._m22 *= matrix2._m22; matrix1._offsetX = matrix2._m11 * matrix1._offsetX + matrix2._offsetX; matrix1._offsetY = matrix2._m22 * matrix1._offsetY + matrix2._offsetY; return; case 36: // S * U case 52: // S|T * U case 66: // U * S case 67: // U * S|T case 68: // U * U matrix1 = new Matrix( matrix1._m11 * matrix2._m11 + matrix1._m12 * matrix2._m21, matrix1._m11 * matrix2._m12 + matrix1._m12 * matrix2._m22, matrix1._m21 * matrix2._m11 + matrix1._m22 * matrix2._m21, matrix1._m21 * matrix2._m12 + matrix1._m22 * matrix2._m22, matrix1._offsetX * matrix2._m11 + matrix1._offsetY * matrix2._m21 + matrix2._offsetX, matrix1._offsetX * matrix2._m12 + matrix1._offsetY * matrix2._m22 + matrix2._offsetY); return; #if DEBUG default: Debug.Fail("Matrix multiply hit an invalid case: " + combinedType); break; #endif } }
/// <summary> /// TransformRect - Internal helper for perf /// </summary> /// <param name="rect"> The Rect to transform. </param> /// <param name="matrix"> The Matrix with which to transform the Rect. </param> internal static void TransformRect(ref Rect rect, ref Matrix matrix) { if (rect.IsEmpty) { return; } MatrixTypes matrixType = matrix._type; // If the matrix is identity, don't worry. if (matrixType == MatrixTypes.TRANSFORM_IS_IDENTITY) { return; } // Scaling if (0 != (matrixType & MatrixTypes.TRANSFORM_IS_SCALING)) { rect._x *= matrix._m11; rect._y *= matrix._m22; rect._width *= matrix._m11; rect._height *= matrix._m22; // Ensure the width is always positive. For example, if there was a reflection about the // y axis followed by a translation into the visual area, the width could be negative. if (rect._width < 0.0) { rect._x += rect._width; rect._width = -rect._width; } // Ensure the height is always positive. For example, if there was a reflection about the // x axis followed by a translation into the visual area, the height could be negative. if (rect._height < 0.0) { rect._y += rect._height; rect._height = -rect._height; } } // Translation if (0 != (matrixType & MatrixTypes.TRANSFORM_IS_TRANSLATION)) { // X rect._x += matrix._offsetX; // Y rect._y += matrix._offsetY; } if (matrixType == MatrixTypes.TRANSFORM_IS_UNKNOWN) { // Al Bunny implementation. Point point0 = matrix.Transform(rect.TopLeft); Point point1 = matrix.Transform(rect.TopRight); Point point2 = matrix.Transform(rect.BottomRight); Point point3 = matrix.Transform(rect.BottomLeft); // Width and height is always positive here. rect._x = Math.Min(Math.Min(point0.X, point1.X), Math.Min(point2.X, point3.X)); rect._y = Math.Min(Math.Min(point0.Y, point1.Y), Math.Min(point2.Y, point3.Y)); rect._width = Math.Max(Math.Max(point0.X, point1.X), Math.Max(point2.X, point3.X)) - rect._x; rect._height = Math.Max(Math.Max(point0.Y, point1.Y), Math.Max(point2.Y, point3.Y)) - rect._y; } }
internal static void CalcGeometryAndBoundsWithTransform(StrokeNodeIterator iterator, DrawingAttributes drawingAttributes, MatrixTypes stylusTipMatrixType, bool calculateBounds, out Geometry geometry, out Rect bounds) { StreamGeometry streamGeometry = new StreamGeometry(); streamGeometry.FillRule = FillRule.Nonzero; StreamGeometryContext streamGeometryContext = streamGeometry.Open(); geometry = streamGeometry; bounds = Rect.Empty; try { List <Point> list = new List <Point>(iterator.Count * 4); int num = iterator.Count * 2; int num2 = 0; for (int i = 0; i < num; i++) { list.Add(new Point(0.0, 0.0)); } List <Point> list2 = new List <Point>(); double lastAngle = 0.0; bool flag = false; Rect rect = new Rect(0.0, 0.0, 0.0, 0.0); for (int j = 0; j < iterator.Count; j++) { StrokeNode strokeNode = iterator[j]; Rect bounds2 = strokeNode.GetBounds(); if (calculateBounds) { bounds.Union(bounds2); } double num3 = Math.Abs(GetAngleDeltaFromLast(strokeNode.PreviousPosition, strokeNode.Position, ref lastAngle)); double num4 = 45.0; if (stylusTipMatrixType == MatrixTypes.TRANSFORM_IS_UNKNOWN) { num4 = 10.0; } else if (bounds2.Height > 40.0 || bounds2.Width > 40.0) { num4 = 20.0; } bool flag2 = num3 > num4 && num3 < 360.0 - num4; double val = rect.Height * rect.Width; double val2 = bounds2.Height * bounds2.Width; bool flag3 = false; if (Math.Min(val, val2) / Math.Max(val, val2) <= 0.7) { flag3 = true; } rect = bounds2; if ((j <= 1 || j >= iterator.Count - 2) | flag2 | flag3) { if (flag2 && !flag && j > 1 && j < iterator.Count - 1) { list2.Clear(); strokeNode.GetPreviousContourPoints(list2); AddFigureToStreamGeometryContext(streamGeometryContext, list2, strokeNode.IsEllipse); flag = true; } list2.Clear(); strokeNode.GetContourPoints(list2); AddFigureToStreamGeometryContext(streamGeometryContext, list2, strokeNode.IsEllipse); } if (!flag2) { flag = false; } Quad connectingQuad = strokeNode.GetConnectingQuad(); if (!connectingQuad.IsEmpty) { list[num2++] = connectingQuad.A; list[num2++] = connectingQuad.B; list.Add(connectingQuad.D); list.Add(connectingQuad.C); } if (strokeNode.IsLastNode && num2 > 0) { int num5 = iterator.Count * 2; int num6 = list.Count - 1; int num7 = num2; for (int k = num5; k <= num6; k++) { list[num7] = list[k]; num7++; } int num8 = num5 - num2; list.RemoveRange(num6 - num8 + 1, num8); int num9 = num2; int num10 = list.Count - 1; while (num9 < num10) { Point value = list[num9]; list[num9] = list[num10]; list[num10] = value; num9++; num10--; } AddFigureToStreamGeometryContext(streamGeometryContext, list, isBezierFigure: false); } } } finally { streamGeometryContext.Close(); geometry.Freeze(); } }
public void SetIdentity() { this._type = MatrixTypes.TRANSFORM_IS_IDENTITY; }
internal static void MultiplyMatrix(ref Matrix matrix1, ref Matrix matrix2) { MatrixTypes type1 = matrix1._type; MatrixTypes type2 = matrix2._type; if (type2 == MatrixTypes.Identity) { return; } if (type1 == MatrixTypes.Identity) { matrix1 = matrix2; return; } if (type2 == MatrixTypes.Translation) { matrix1._offsetX += matrix2._offsetX; matrix1._offsetY += matrix2._offsetY; if (type1 != MatrixTypes.Unknown) { matrix1._type |= MatrixTypes.Translation; } return; } // Check for the first value being a translate if (type1 == MatrixTypes.Translation) { double offsetX = matrix1._offsetX; double offsetY = matrix1._offsetY; matrix1 = matrix2; matrix1._offsetX = offsetX * matrix2._m11 + offsetY * matrix2._m21 + matrix2._offsetX; matrix1._offsetY = offsetX * matrix2._m12 + offsetY * matrix2._m22 + matrix2._offsetY; if (type2 == MatrixTypes.Unknown) { matrix1._type = MatrixTypes.Unknown; } else { matrix1._type = MatrixTypes.Scaling | MatrixTypes.Translation; } return; } // trans1._type | trans2._type // 7 6 5 4 | 3 2 1 0 int combinedType = ((int)type1 << 4) | (int)type2; switch (combinedType) { case 34: // S * S // 2 multiplications matrix1._m11 *= matrix2._m11; matrix1._m22 *= matrix2._m22; return; case 35: // S * S|T matrix1._m11 *= matrix2._m11; matrix1._m22 *= matrix2._m22; matrix1._offsetX = matrix2._offsetX; matrix1._offsetY = matrix2._offsetY; // Transform set to Translate and Scale matrix1._type = MatrixTypes.Translation | MatrixTypes.Scaling; return; case 50: // S|T * S matrix1._m11 *= matrix2._m11; matrix1._m22 *= matrix2._m22; matrix1._offsetX *= matrix2._m11; matrix1._offsetY *= matrix2._m22; return; case 51: // S|T * S|T matrix1._m11 *= matrix2._m11; matrix1._m22 *= matrix2._m22; matrix1._offsetX = matrix2._m11 * matrix1._offsetX + matrix2._offsetX; matrix1._offsetY = matrix2._m22 * matrix1._offsetY + matrix2._offsetY; return; case 36: // S * U case 52: // S|T * U case 66: // U * S case 67: // U * S|T case 68: // U * U matrix1 = new Matrix( matrix1._m11 * matrix2._m11 + matrix1._m12 * matrix2._m21, matrix1._m11 * matrix2._m12 + matrix1._m12 * matrix2._m22, matrix1._m21 * matrix2._m11 + matrix1._m22 * matrix2._m21, matrix1._m21 * matrix2._m12 + matrix1._m22 * matrix2._m22, matrix1._offsetX * matrix2._m11 + matrix1._offsetY * matrix2._m21 + matrix2._offsetX, matrix1._offsetX * matrix2._m12 + matrix1._offsetY * matrix2._m22 + matrix2._offsetY); return; default: break; } }
/// <summary> /// Method for creating the game matrix. /// </summary> /// <param name="type">Matrix type</param> public void CreateMatrix(MatrixTypes type) { this.matrix = (Matrix)new MatrixFactory().CreateMatrix(type); }
public void SetIdentity() { _type = MatrixTypes.Identity; }
/// <summary> /// Method for creating the game matrix. /// </summary> /// <param name="type">Matrix type</param> public void CreateMatrix(MatrixTypes type) { this.matrix = (Matrix) new MatrixFactory().CreateMatrix(type); }
/// <summary> /// Calculate the StreamGeometry for the StrokeNodes. /// This method is one of our most sensitive perf paths. It has been optimized to /// create the minimum path figures in the StreamGeometry. There are two structures /// we create for each point in a stroke, the strokenode and the connecting quad. Adding /// strokenodes is very expensive later when MIL renders it, so this method has been optimized /// to only add strokenodes when either pressure changes, or the angle of the stroke changes. /// </summary> internal static void CalcGeometryAndBoundsWithTransform(StrokeNodeIterator iterator, DrawingAttributes drawingAttributes, MatrixTypes stylusTipMatrixType, bool calculateBounds, out Geometry geometry, out Rect bounds) { Debug.Assert(iterator != null); Debug.Assert(drawingAttributes != null); StreamGeometry streamGeometry = new StreamGeometry(); streamGeometry.FillRule = FillRule.Nonzero; StreamGeometryContext context = streamGeometry.Open(); geometry = streamGeometry; bounds = Rect.Empty; try { List<Point> connectingQuadPoints = new List<Point>(iterator.Count * 4); //the index that the cb quad points are copied to int cdIndex = iterator.Count * 2; //the index that the ab quad points are copied to int abIndex = 0; for (int x = 0; x < cdIndex; x++) { //initialize so we can start copying to cdIndex later connectingQuadPoints.Add(new Point(0d, 0d)); } List<Point> strokeNodePoints = new List<Point>(); double lastAngle = 0.0d; bool previousPreviousNodeRendered = false; Rect lastRect = new Rect(0, 0, 0, 0); for (int index = 0; index < iterator.Count; index++) { StrokeNode strokeNode = iterator[index]; System.Diagnostics.Debug.Assert(true == strokeNode.IsValid); //the only code that calls this with !calculateBounds //is dynamic rendering, which already draws enough strokeNodes //to hide any visual artifacts. //static rendering calculatesBounds, and we use those //bounds below to figure out what angle to lay strokeNodes down for. Rect strokeNodeBounds = strokeNode.GetBounds(); if (calculateBounds) { bounds.Union(strokeNodeBounds); } //if the angle between this and the last position has changed //too much relative to the angle between the last+1 position and the last position //we need to lay down stroke node double delta = Math.Abs(GetAngleDeltaFromLast(strokeNode.PreviousPosition, strokeNode.Position, ref lastAngle)); double angleTolerance = 45d; if (stylusTipMatrixType == MatrixTypes.TRANSFORM_IS_UNKNOWN) { //probably a skew is thrown in, we need to fall back to being very conservative //about how many strokeNodes we prune angleTolerance = 10d; } else if (strokeNodeBounds.Height > 40d || strokeNodeBounds.Width > 40d) { //if the strokeNode gets above a certain size, we need to lay down more strokeNodes //to prevent visual artifacts angleTolerance = 20d; } bool directionChanged = delta > angleTolerance && delta < (360d - angleTolerance); double prevArea = lastRect.Height * lastRect.Width; double currArea = strokeNodeBounds.Height * strokeNodeBounds.Width; bool areaChangedOverThreshold = false; if ((Math.Min(prevArea, currArea) / Math.Max(prevArea, currArea)) <= 0.70d) { //the min area is < 70% of the max area areaChangedOverThreshold = true; } lastRect = strokeNodeBounds; //render the stroke node for the first two nodes and last two nodes always if (index <= 1 || index >= iterator.Count - 2 || directionChanged || areaChangedOverThreshold) { //special case... the direction has changed and we need to //insert a stroke node in the StreamGeometry before we render the current one if (directionChanged && !previousPreviousNodeRendered && index > 1 && index < iterator.Count - 1) { //insert a stroke node for the previous node strokeNodePoints.Clear(); strokeNode.GetPreviousContourPoints(strokeNodePoints); AddFigureToStreamGeometryContext(context, strokeNodePoints, strokeNode.IsEllipse/*isBezierFigure*/); previousPreviousNodeRendered = true; } //render the stroke node strokeNodePoints.Clear(); strokeNode.GetContourPoints(strokeNodePoints); AddFigureToStreamGeometryContext(context, strokeNodePoints, strokeNode.IsEllipse/*isBezierFigure*/); } if (!directionChanged) { previousPreviousNodeRendered = false; } //add the end points of the connecting quad Quad quad = strokeNode.GetConnectingQuad(); if (!quad.IsEmpty) { connectingQuadPoints[abIndex++] = quad.A; connectingQuadPoints[abIndex++] = quad.B; connectingQuadPoints.Add(quad.D); connectingQuadPoints.Add(quad.C); } if (strokeNode.IsLastNode) { Debug.Assert(index == iterator.Count - 1); if (abIndex > 0) { //we added something to the connecting quad points. //now we need to do three things //1) Shift the dc points down to the ab points int cbStartIndex = iterator.Count * 2; int cbEndIndex = connectingQuadPoints.Count - 1; for (int i = abIndex, j = cbStartIndex; j <= cbEndIndex; i++, j++) { connectingQuadPoints[i] = connectingQuadPoints[j]; } //2) trim the exess off the end of the array int countToRemove = cbStartIndex - abIndex; connectingQuadPoints.RemoveRange((cbEndIndex - countToRemove) + 1, countToRemove); //3) reverse the dc points to make them cd points for (int i = abIndex, j = connectingQuadPoints.Count - 1; i < j; i++, j--) { Point temp = connectingQuadPoints[i]; connectingQuadPoints[i] = connectingQuadPoints[j]; connectingQuadPoints[j] = temp; } //now render away! AddFigureToStreamGeometryContext(context, connectingQuadPoints, false/*isBezierFigure*/); } } } } finally { context.Close(); geometry.Freeze(); } }
///<summary> /// Sets the transform to /// / m11, m12, 0 \ /// | m21, m22, 0 | /// \ offsetX, offsetY, 1 / /// where offsetX, offsetY is the translation. ///</summary> private void SetMatrix(double m11, double m12, double m21, double m22, double offsetX, double offsetY, MatrixTypes type) { this._m11 = m11; this._m12 = m12; this._m21 = m21; this._m22 = m22; this._offsetX = offsetX; this._offsetY = offsetY; this._type = type; }