示例#1
0
        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());
        }
示例#3
0
        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();
        }
示例#5
0
        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;
            }
        }
示例#6
0
 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;
 }
示例#7
0
 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;
 }
示例#8
0
 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;
 }
示例#9
0
        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);
        }
示例#10
0
 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();
 }
示例#11
0
 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;
 }
示例#12
0
        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();
        }
示例#13
0
        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;
        }
示例#14
0
 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;
     }
 }
示例#15
0
        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));
        }
示例#17
0
 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;
     }
 }
示例#18
0
        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;
                }
            }
        }
示例#19
0
        /// <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
            }
        }
示例#20
0
        /// <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;
            }
        }
示例#21
0
        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();
            }
        }
示例#22
0
 public void SetIdentity()
 {
     this._type = MatrixTypes.TRANSFORM_IS_IDENTITY;
 }
示例#23
0
        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);
 }
示例#25
0
 public void SetIdentity()
 {
     _type = MatrixTypes.Identity;
 }
示例#26
0
 /// <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);
 }
示例#27
0
        /// <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();
            }
        }
示例#28
0
文件: Matrix.cs 项目: JianwenSun/cc
 ///<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;
 }