예제 #1
0
        SKMatrix CreateMatrix()
        {
            SKMatrix matrix = SKMatrix.CreateIdentity();

            SKRect drawableBounds  = _drawableBounds;
            float  halfStrokeWidth = _skPaint.StrokeWidth / 2;

            drawableBounds.Left   += halfStrokeWidth;
            drawableBounds.Top    += halfStrokeWidth;
            drawableBounds.Right  -= halfStrokeWidth;
            drawableBounds.Bottom -= halfStrokeWidth;

            float widthScale  = drawableBounds.Width / _pathFillBounds.Width;
            float heightScale = drawableBounds.Height / _pathFillBounds.Height;

            switch (_stretch)
            {
            case Stretch.None:
                drawableBounds = _drawableBounds;
                float adjustX = Math.Min(0, _pathStrokeBounds.Left);
                float adjustY = Math.Min(0, _pathStrokeBounds.Top);
                if (adjustX < 0 || adjustY < 0)
                {
                    matrix = SKMatrix.CreateTranslation(-adjustX, -adjustY);
                }
                break;

            case Stretch.Fill:
                matrix = SKMatrix.CreateScale(widthScale, heightScale);
                matrix = matrix.PostConcat(
                    SKMatrix.CreateTranslation(drawableBounds.Left - widthScale * _pathFillBounds.Left,
                                               drawableBounds.Top - heightScale * _pathFillBounds.Top));
                break;

            case Stretch.Uniform:
                float minScale = Math.Min(widthScale, heightScale);
                matrix = SKMatrix.CreateScale(minScale, minScale);
                matrix = matrix.PostConcat(
                    SKMatrix.CreateTranslation(drawableBounds.Left - (minScale * _pathFillBounds.Left) + (drawableBounds.Width - (minScale * _pathFillBounds.Width)) / 2,
                                               drawableBounds.Top - (minScale * _pathFillBounds.Top) + (drawableBounds.Height - (minScale * _pathFillBounds.Height)) / 2));
                break;

            case Stretch.UniformToFill:
                float maxScale = Math.Max(widthScale, heightScale);
                matrix = SKMatrix.CreateScale(maxScale, maxScale);
                matrix = matrix.PostConcat(
                    SKMatrix.CreateTranslation(drawableBounds.Left - (maxScale * _pathFillBounds.Left),
                                               drawableBounds.Top - (maxScale * _pathFillBounds.Top)));
                break;
            }

            return(matrix);
        }
예제 #2
0
        /// <summary>
        /// 单指操纵
        /// </summary>
        /// <param name="prevPoint"></param>
        /// <param name="newPoint"></param>
        /// <param name="pivotPoint"></param>
        /// <returns></returns>
        public SKMatrix OneFingerManipulate(SKPoint prevPoint, SKPoint newPoint, SKPoint pivotPoint)
        {
            if (Mode == TouchManipulationMode.None)
            {
                return(SKMatrix.CreateIdentity());
            }

            SKMatrix touchMatrix = SKMatrix.CreateIdentity();
            SKPoint  delta       = newPoint - prevPoint;

            if (Mode == TouchManipulationMode.ScaleDualRotate)  // One-finger rotation
            {
                SKPoint oldVector = prevPoint - pivotPoint;
                SKPoint newVector = newPoint - pivotPoint;

                float scale = Magnitude(newVector) / Magnitude(oldVector);


                // Avoid rotation if fingers are too close to center
                if (Magnitude(newVector) > 30 && Magnitude(oldVector) > 30)
                {
                    float prevAngle = (float)Math.Atan2(oldVector.Y, oldVector.X);
                    float newAngle  = (float)Math.Atan2(newVector.Y, newVector.X);

                    // Calculate rotation matrix
                    float angle = newAngle - prevAngle;
                    touchMatrix = SKMatrix.CreateRotation(angle, pivotPoint.X, pivotPoint.Y);

                    // Effectively rotate the old vector
                    float magnitudeRatio = Magnitude(oldVector) / Magnitude(newVector);
                    oldVector.X = magnitudeRatio * newVector.X;
                    oldVector.Y = magnitudeRatio * newVector.Y;

                    // Recalculate delta
                    delta = newVector - oldVector;
                }

                if (!float.IsNaN(scale) && !float.IsInfinity(scale))
                {
                    var tm = SKMatrix.CreateScale(scale, scale, pivotPoint.X, pivotPoint.Y);
                    touchMatrix.PostConcat(tm);
                }
            }

            // Multiply the rotation matrix by a translation matrix
            touchMatrix.PostConcat(SKMatrix.CreateTranslation(delta.X, delta.Y));

            return(touchMatrix);
        }
예제 #3
0
        private void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
        {
            SKImageInfo info    = args.Info;
            SKSurface   surface = args.Surface;
            SKCanvas    canvas  = surface.Canvas;

            canvas.Clear();

            float xCenter = info.Width / 2;
            float yCenter = info.Height / 2;

            SKMatrix   matrix   = SKMatrix.MakeTranslation(-xCenter, -yCenter);
            SKMatrix44 matrix44 = SKMatrix44.CreateIdentity();

            matrix44.PostConcat(SKMatrix44.CreateRotationDegrees(1, 0, 0, _Deg));

            SKMatrix44 perspectiveMatrix = SKMatrix44.CreateIdentity();

            perspectiveMatrix[3, 2] = -1 / 5000f;
            matrix44.PostConcat(perspectiveMatrix);

            SKMatrix.PostConcat(ref matrix, matrix44.Matrix);
            SKMatrix.PostConcat(ref matrix, SKMatrix.MakeTranslation(xCenter, yCenter));
            canvas.SetMatrix(matrix);
            float xBitmap = xCenter - CurrentBitmap.Width / 2;
            float yBitmap = yCenter - CurrentBitmap.Height / 2;

            canvas.DrawBitmap(CurrentBitmap, xBitmap, yBitmap);
        }
        void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
        {
            SKImageInfo info    = args.Info;
            SKSurface   surface = args.Surface;
            SKCanvas    canvas  = surface.Canvas;

            canvas.Clear();

            TaperSide   taperSide     = (TaperSide)taperSidePicker.SelectedIndex;
            TaperCorner taperCorner   = (TaperCorner)taperCornerPicker.SelectedIndex;
            float       taperFraction = (float)taperFractionSlider.Value;

            SKMatrix taperMatrix =
                TaperTransform.Make(new SKSize(bitmap.Width, bitmap.Height),
                                    taperSide, taperCorner, taperFraction);

            // Display the matrix in the lower-right corner
            SKSize matrixSize = matrixDisplay.Measure(taperMatrix);

            matrixDisplay.Paint(canvas, taperMatrix,
                                new SKPoint(info.Width - matrixSize.Width,
                                            info.Height - matrixSize.Height));

            // Center bitmap on canvas
            float x = (info.Width - bitmap.Width) / 2;
            float y = (info.Height - bitmap.Height) / 2;

            SKMatrix matrix = SKMatrix.MakeTranslation(-x, -y);

            SKMatrix.PostConcat(ref matrix, taperMatrix);
            SKMatrix.PostConcat(ref matrix, SKMatrix.MakeTranslation(x, y));

            canvas.SetMatrix(matrix);
            canvas.DrawBitmap(bitmap, x, y);
        }
예제 #5
0
        public static SKPath?GetClipPathClipPath(SvgClipPath svgClipPath, SKRect skBounds, HashSet <Uri> uris, CompositeDisposable disposable)
        {
            var svgClipPathRef = svgClipPath.GetUriElementReference <SvgClipPath>("clip-path", uris);

            if (svgClipPathRef == null || svgClipPathRef.Children == null)
            {
                return(null);
            }

            var clipPath = GetClipPath(svgClipPathRef, skBounds, uris, disposable);

            if (clipPath != null)
            {
                var skMatrix = SKMatrix.MakeIdentity();

                if (svgClipPathRef.ClipPathUnits == SvgCoordinateUnits.ObjectBoundingBox)
                {
                    var skScaleMatrix = SKMatrix.MakeScale(skBounds.Width, skBounds.Height);
                    SKMatrix.PostConcat(ref skMatrix, ref skScaleMatrix);

                    var skTranslateMatrix = SKMatrix.MakeTranslation(skBounds.Left, skBounds.Top);
                    SKMatrix.PostConcat(ref skMatrix, ref skTranslateMatrix);
                }

                var skTransformsMatrix = SvgTransformsExtensions.ToSKMatrix(svgClipPathRef.Transforms);
                SKMatrix.PostConcat(ref skMatrix, ref skTransformsMatrix);

                clipPath.Transform(skMatrix);
            }

            return(clipPath);
        }
        void Manipulate()
        {
            TouchManipulationInfo[] infos = new TouchManipulationInfo[touchDictionary.Count];
            touchDictionary.Values.CopyTo(infos, 0);
            SKMatrix touchMatrix = SKMatrix.MakeIdentity();

            if (infos.Length == 1)
            {
                SKPoint prevPoint  = infos[0].PreviousPoint;
                SKPoint newPoint   = infos[0].NewPoint;
                SKPoint pivotPoint = Matrix.MapPoint(bitmap.Width / 2, bitmap.Height / 2);

                touchMatrix = TouchManager.OneFingerManipulate(prevPoint, newPoint, pivotPoint);
            }
            else if (infos.Length >= 2)
            {
                int     pivotIndex = infos[0].NewPoint == infos[0].PreviousPoint ? 0 : 1;
                SKPoint pivotPoint = infos[pivotIndex].NewPoint;
                SKPoint newPoint   = infos[1 - pivotIndex].NewPoint;
                SKPoint prevPoint  = infos[1 - pivotIndex].PreviousPoint;

                touchMatrix = TouchManager.TwoFingerManipulate(prevPoint, newPoint, pivotPoint);
            }

            SKMatrix matrix = Matrix;

            SKMatrix.PostConcat(ref matrix, touchMatrix);
            Matrix = matrix;
        }
        void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
        {
            SKImageInfo info    = args.Info;
            SKSurface   surface = args.Surface;
            SKCanvas    canvas  = surface.Canvas;

            canvas.Clear();

            // Calculate perspective matrix
            SKMatrix perspectiveMatrix = SKMatrix.MakeIdentity();

            perspectiveMatrix.Persp0 = (float)persp0Slider.Value / 100;
            perspectiveMatrix.Persp1 = (float)persp1Slider.Value / 100;

            // Center of screen
            float xCenter = info.Width / 2;
            float yCenter = info.Height / 2;

            SKMatrix matrix = SKMatrix.MakeTranslation(-xCenter, -yCenter);

            SKMatrix.PostConcat(ref matrix, perspectiveMatrix);
            SKMatrix.PostConcat(ref matrix, SKMatrix.MakeTranslation(xCenter, yCenter));

            // Coordinates to center bitmap on canvas
            float x = xCenter - bitmap.Width / 2;
            float y = yCenter - bitmap.Height / 2;

            canvas.SetMatrix(matrix);
            canvas.DrawBitmap(bitmap, x, y);
        }
예제 #8
0
        public SKMatrix MatrixToAspectCoordinates()
        {
            SKMatrix A = SKMatrix.MakeTranslation(-this.AbsolutePosition.X, -this.AbsolutePosition.Y);
            SKMatrix B = SKMatrix.MakeScale(1.0f / this.ScaleFactor, 1.0f / this.ScaleFactor);

            SKMatrix.PostConcat(ref A, B);
            return(A);
        }
예제 #9
0
        public void MatrixCanPostConcat()
        {
            var a = SKMatrix.MakeTranslation(10, 20);
            var b = SKMatrix.MakeTranslation(5, 7);

            SKMatrix.PostConcat(ref a, ref b);

            Assert.Equal(SKMatrix.MakeTranslation(15, 27).Values, a.Values);
        }
예제 #10
0
        /// <summary>
        /// Updates the particle's position and orientation based on the given time
        /// </summary>
        /// <para>Call this method first and then <see cref="Paint"/></para>
        /// <para>This method doesn't need to be called on the UI/Main thread</para>
        /// <param name="absoluteElapsedMillis"></param>
        public virtual void Update(long absoluteElapsedMillis, SKSize scale)
        {
            // Determine elapsed time since this particles was created
            var elapsedMillis = absoluteElapsedMillis - _absoluteElapsedMillisPrevious;

            if (_absoluteElapsedMillisPrevious == 0)
            {
                _absoluteElapsedMillisPrevious = absoluteElapsedMillis;
                return;
            }

            _internalAbsoluteMillis       += elapsedMillis;
            _absoluteElapsedMillisPrevious = absoluteElapsedMillis;

            // Traversed distance = speed x time
            var dist = TranslationSpeed * _internalAbsoluteMillis * 0.001;

            // New position
            var deg2radFactor = 0.0174533;
            var angle         = Direction * deg2radFactor;

            Position = InitialPosition + new SKPoint
            {
                X = (float)(dist * Math.Cos(angle)),
                Y = (float)(dist * Math.Sin(angle))
            };

            TransformationMatrix = SKMatrix.CreateTranslation(-Position.X, -Position.Y);

            // New Scale
            TransformationMatrix = TransformationMatrix.PostConcat(SKMatrix.CreateScale(scale.Width, scale.Height));

            // New Orientation
            Orientation = InitialOrientation + new SKPoint3
            {
                X = _internalAbsoluteMillis * 0.001f * RotationSpeed.X,
                Y = _internalAbsoluteMillis * 0.001f * RotationSpeed.Y,
                Z = _internalAbsoluteMillis * 0.001f * RotationSpeed.Z
            };

            _totalRotationMatrix.SetIdentity();

            _xAxisRotationMatrix.SetRotationAboutDegrees(1, 0, 0, Orientation.X);
            _totalRotationMatrix.PostConcat(_xAxisRotationMatrix);

            _yAxisRotationMatrix.SetRotationAboutDegrees(0, 1, 0, Orientation.Y);
            _totalRotationMatrix.PostConcat(_yAxisRotationMatrix);

            _zAxisRotationMatrix.SetRotationAboutDegrees(0, 0, 1, Orientation.Z);
            _totalRotationMatrix.PostConcat(_zAxisRotationMatrix);

            TransformationMatrix = TransformationMatrix.PostConcat(_totalRotationMatrix.Matrix);

            // Translate back
            TransformationMatrix = TransformationMatrix.PostConcat(SKMatrix.CreateTranslation(Position.X, Position.Y));
        }
예제 #11
0
 private void HandlePinch(object sender, PinchGestureUpdatedEventArgs e)
 {
     switch (e.Status)
     {
     case GestureStatus.Running:
         SKPoint  pivotPt = ToUntransformedCanvasPt((float)(e.ScaleOrigin.X * _canvasV.Width), (float)(e.ScaleOrigin.Y * _canvasV.Height));
         SKMatrix deltaM  = SKMatrix.MakeScale((float)e.Scale, (float)e.Scale, pivotPt.X, pivotPt.Y);
         SKMatrix.PostConcat(ref _m, deltaM);
         _canvasV.InvalidateSurface();
         break;
     }
 }
예제 #12
0
 protected override void OnPaintSurface(SKPaintSurfaceEventArgs e)
 {
     base.OnPaintSurface(e);
     e.Surface.Canvas.Clear();
     if (!string.IsNullOrEmpty(ResourceId))
     {
         EnsurePicture();
         SKMatrix scaleMatrix       = GetScaleMatrix(e.Info);
         SKMatrix translationMatrix = GetTranslationMatrix(e.Info, scaleMatrix);
         SKMatrix.PostConcat(ref scaleMatrix, translationMatrix);
         e.Surface.Canvas.DrawPicture(_skSvg.Picture, ref scaleMatrix);
     }
 }
예제 #13
0
        public void Multiply(Matrix matrix, MatrixOrder order)
        {
            var m = ((Matrix)matrix).SKMatrix;

            if (order == MatrixOrder.Append)
            {
                SKMatrix.PostConcat(ref _m, ref m);
            }
            else
            {
                SKMatrix.PreConcat(ref _m, ref m);
            }
        }
예제 #14
0
        public void Translate(float left, float top, MatrixOrder order)
        {
            var m = SKMatrix.MakeTranslation(left, top);

            if (order == MatrixOrder.Append)
            {
                SKMatrix.PostConcat(ref _m, ref m);
            }
            else
            {
                SKMatrix.PreConcat(ref _m, ref m);
            }
        }
예제 #15
0
        public void Scale(float width, float height, MatrixOrder order)
        {
            var m = SKMatrix.MakeScale(width, height);

            if (order == MatrixOrder.Append)
            {
                SKMatrix.PostConcat(ref _m, ref m);
            }
            else
            {
                SKMatrix.PreConcat(ref _m, ref m);
            }
        }
예제 #16
0
        public void RotateAt(float angleDegrees, PointF midPoint, MatrixOrder order)
        {
            var m = SKMatrix.MakeRotationDegrees(angleDegrees, midPoint.X, midPoint.Y);

            if (order == MatrixOrder.Append)
            {
                SKMatrix.PostConcat(ref _m, ref m);
            }
            else
            {
                SKMatrix.PreConcat(ref _m, ref m);
            }
        }
예제 #17
0
        public static SKPath?GetClipPath(SvgClipPath svgClipPath, SKRect skBounds, HashSet <Uri> uris, CompositeDisposable disposable)
        {
            var skPathClip = default(SKPath);

            var clipPathClipPath = GetClipPathClipPath(svgClipPath, skBounds, uris, disposable);

            if (clipPathClipPath != null && !clipPathClipPath.IsEmpty)
            {
                skPathClip = clipPathClipPath;
            }

            var clipPath = GetClipPath(svgClipPath.Children, skBounds, uris, disposable);

            if (clipPath != null)
            {
                var skMatrix = SKMatrix.MakeIdentity();

                if (svgClipPath.ClipPathUnits == SvgCoordinateUnits.ObjectBoundingBox)
                {
                    var skScaleMatrix = SKMatrix.MakeScale(skBounds.Width, skBounds.Height);
                    SKMatrix.PostConcat(ref skMatrix, ref skScaleMatrix);

                    var skTranslateMatrix = SKMatrix.MakeTranslation(skBounds.Left, skBounds.Top);
                    SKMatrix.PostConcat(ref skMatrix, ref skTranslateMatrix);
                }

                var skTransformsMatrix = SvgTransformsExtensions.ToSKMatrix(svgClipPath.Transforms);
                SKMatrix.PostConcat(ref skMatrix, ref skTransformsMatrix);

                clipPath.Transform(skMatrix);

                if (skPathClip == null)
                {
                    skPathClip = clipPath;
                }
                else
                {
                    var result = skPathClip.Op(clipPath, SKPathOp.Intersect);
                    disposable.Add(result);
                    skPathClip = result;
                }
            }

            if (skPathClip == null)
            {
                skPathClip = new SKPath();
                disposable.Add(skPathClip);
            }

            return(skPathClip);
        }
예제 #18
0
        private SKMatrix ComputeMatrix(SKSize size, SKPoint ptUL, SKPoint ptUR, SKPoint ptLL, SKPoint?ptLR = null)
        {
            // Scale transform
            SKMatrix S = SKMatrix.CreateScale(1 / size.Width, 1 / size.Height);

            // Affine transform
            SKMatrix A = new SKMatrix
            {
                ScaleX = ptUR.X - ptUL.X,
                SkewY  = ptUR.Y - ptUL.Y,
                SkewX  = ptLL.X - ptUL.X,
                ScaleY = ptLL.Y - ptUL.Y,
                TransX = ptUL.X,
                TransY = ptUL.Y,
                Persp2 = 1
            };

            // Non-Affine transform
            SKMatrix N = SKMatrix.CreateIdentity();

            if (ptLR.HasValue)
            {
                SKMatrix inverseA;
                A.TryInvert(out inverseA);
                SKPoint abPoint = inverseA.MapPoint(ptLR.Value);
                float   a       = abPoint.X;
                float   b       = abPoint.Y;

                float scaleX = a / (a + b - 1);
                float scaleY = b / (a + b - 1);

                N = new SKMatrix
                {
                    ScaleX = scaleX,
                    ScaleY = scaleY,
                    Persp0 = scaleX - 1,
                    Persp1 = scaleY - 1,
                    Persp2 = 1
                };
            }

            // Multiply S * N * A
            SKMatrix result = SKMatrix.CreateIdentity();

            SKMatrix.PostConcat(ref result, S);
            SKMatrix.PostConcat(ref result, N);
            SKMatrix.PostConcat(ref result, A);

            return(result);
        }
예제 #19
0
        void DrawRotatedWithMatrices(SKCanvas canvas, SKPath path, SKPaint paint, float degrees, int cx, int cy)
        {
            var result     = SKMatrix.MakeIdentity();
            var translate  = SKMatrix.MakeTranslation(-cx, -cy);
            var rotate     = SKMatrix.MakeRotationDegrees(degrees);
            var translate2 = SKMatrix.MakeTranslation(cx, cy);

            SKMatrix.PostConcat(ref result, translate);
            SKMatrix.PostConcat(ref result, rotate);
            SKMatrix.PostConcat(ref result, translate2);

            path.Transform(result);
            canvas.DrawPath(path, paint);
        }
        void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
        {
            SKImageInfo info    = args.Info;
            SKSurface   surface = args.Surface;
            SKCanvas    canvas  = surface.Canvas;

            canvas.Clear();

            // Find center of canvas
            float xCenter = info.Width / 2;
            float yCenter = info.Height / 2;

            // Translate center to origin
            SKMatrix matrix = SKMatrix.MakeTranslation(-xCenter, -yCenter);

            // Scale so text fits
            float scale = Math.Min(info.Width / textBounds.Width,
                                   info.Height / textBounds.Height);

            SKMatrix.PostConcat(ref matrix, SKMatrix.MakeScale(scale, scale));

            // Calculate composite 3D transforms
            float depth = 0.75f * scale * textBounds.Width;

            SKMatrix44 matrix44 = SKMatrix44.CreateIdentity();

            matrix44.PostConcat(SKMatrix44.CreateRotationDegrees(1, 0, 0, xRotationDegrees));
            matrix44.PostConcat(SKMatrix44.CreateRotationDegrees(0, 1, 0, yRotationDegrees));
            matrix44.PostConcat(SKMatrix44.CreateRotationDegrees(0, 0, 1, zRotationDegrees));

            SKMatrix44 perspectiveMatrix = SKMatrix44.CreateIdentity();

            perspectiveMatrix[3, 2] = -1 / depth;
            matrix44.PostConcat(perspectiveMatrix);

            // Concatenate with 2D matrix
            SKMatrix.PostConcat(ref matrix, matrix44.Matrix);

            // Translate back to center
            SKMatrix.PostConcat(ref matrix,
                                SKMatrix.MakeTranslation(xCenter, yCenter));

            // Set the matrix and display the text
            canvas.SetMatrix(matrix);
            float xText = xCenter - textBounds.MidX;
            float yText = yCenter - textBounds.MidY;

            canvas.DrawText(text, xText, yText, textPaint);
        }
예제 #21
0
        void Manipulate()
        {
            TouchManipulationInfo[] infos = new TouchManipulationInfo[touchDictionary.Count];
            touchDictionary.Values.CopyTo(infos, 0);
            SKMatrix touchMatrix = SKMatrix.MakeIdentity();

            if (infos.Length == 1)
            {
                SKPoint prevPoint  = infos[0].PreviousPoint;
                SKPoint newPoint   = infos[0].NewPoint;
                SKPoint pivotPoint = Matrix.MapPoint(bitmap.Width / 2, bitmap.Height / 2);

                touchMatrix = TouchManager.OneFingerManipulate(prevPoint, newPoint, pivotPoint);
            }
            else if (infos.Length >= 2)
            {
                int     pivotIndex = infos[0].NewPoint == infos[0].PreviousPoint ? 0 : 1;
                SKPoint pivotPoint = infos[pivotIndex].NewPoint;
                SKPoint newPoint   = infos[1 - pivotIndex].NewPoint;
                SKPoint prevPoint  = infos[1 - pivotIndex].PreviousPoint;

                touchMatrix = TouchManager.TwoFingerManipulate(prevPoint, newPoint, pivotPoint);
            }

            SKMatrix matrix = Matrix;

            SKMatrix.PostConcat(ref matrix, touchMatrix);

            // что бы не уменьшить ниже нижнего
            if (Math.Abs(matrix.ScaleX) < 0.1 &&
                Math.Abs(matrix.ScaleY) < 0.1 &&
                Math.Abs(matrix.SkewX) < 0.1 &&
                Math.Abs(matrix.SkewY) < 0.1)
            {
                return;
            }

            // что бы не поднивать выше верхнего
            if (Math.Abs(matrix.ScaleX) > 4.0 &&
                Math.Abs(matrix.ScaleY) > 4.0 ||
                Math.Abs(matrix.SkewX) > 4.0 &&
                Math.Abs(matrix.SkewY) > 4.0)
            {
                return;
            }

            Matrix = matrix;
        }
        /// <summary>
        /// 2本指での操作
        /// </summary>
        /// <param name="prevPoint"></param>
        /// <param name="newPoint"></param>
        /// <param name="pivotPoint"></param>
        /// <returns></returns>
        public SKMatrix TwoFingerManipulate(SKPoint prevPoint, SKPoint newPoint, SKPoint pivotPoint)
        {
            SKMatrix touchMatrix = SKMatrix.CreateIdentity();
            SKPoint  oldVector   = prevPoint - pivotPoint;
            SKPoint  newVector   = newPoint - pivotPoint;

            if (Mode == TouchManipulationMode.ScaleRotate ||
                Mode == TouchManipulationMode.ScaleDualRotate)
            {
                // Find angles from pivot point to touch points
                float oldAngle = (float)Math.Atan2(oldVector.Y, oldVector.X);
                float newAngle = (float)Math.Atan2(newVector.Y, newVector.X);

                // Calculate rotation matrix
                float angle = newAngle - oldAngle;
                touchMatrix = SKMatrix.CreateRotation(angle, pivotPoint.X, pivotPoint.Y);

                // Effectively rotate the old vector
                float magnitudeRatio = Magnitude(oldVector) / Magnitude(newVector);
                oldVector.X = magnitudeRatio * newVector.X;
                oldVector.Y = magnitudeRatio * newVector.Y;
            }

            float scaleX = 1;
            float scaleY = 1;

            if (Mode == TouchManipulationMode.AnisotropicScale)
            {
                scaleX = newVector.X / oldVector.X;
                scaleY = newVector.Y / oldVector.Y;
            }
            else if (Mode == TouchManipulationMode.IsotropicScale ||
                     Mode == TouchManipulationMode.ScaleRotate ||
                     Mode == TouchManipulationMode.ScaleDualRotate)
            {
                scaleX = scaleY = Magnitude(newVector) / Magnitude(oldVector);
            }

            if (!float.IsNaN(scaleX) && !float.IsInfinity(scaleX) &&
                !float.IsNaN(scaleY) && !float.IsInfinity(scaleY))
            {
                //SKMatrix.PostConcat(ref touchMatrix,
                //   SKMatrix.CreateScale(scaleX, scaleY, pivotPoint.X, pivotPoint.Y));
                touchMatrix = touchMatrix.PostConcat(SKMatrix.CreateScale(scaleX, scaleY, pivotPoint.X, pivotPoint.Y));
            }

            return(touchMatrix);
        }
        public PathTransformPage()
        {
            Title = "Path Transform";

            SKCanvasView canvasView = new SKCanvasView();

            canvasView.PaintSurface += OnCanvasViewPaintSurface;
            Content = canvasView;

            SKMatrix matrix = SKMatrix.MakeScale(3, 3);

            SKMatrix.PostConcat(ref matrix, SKMatrix.MakeRotationDegrees(360f / 22));
            SKMatrix.PostConcat(ref matrix, SKMatrix.MakeTranslation(300, 300));

            transformedPath.Transform(matrix);
        }
예제 #24
0
        public void Rotate(float elementRotation, MatrixOrder append)
        {
            var rot = SKMatrix.MakeRotationDegrees(elementRotation);

            var main = new SKMatrix(M11, M12, OffsetX, M21, M22, OffsetY, 0, 0, 1);

            if (append == MatrixOrder.Prepend)
            {
                SKMatrix.PreConcat(ref main, rot);
            }
            else
            {
                SKMatrix.PostConcat(ref main, rot);
            }

            this.SetMatrix(main.ScaleX, main.SkewX, main.SkewY, main.ScaleY, main.TransX, main.TransY,
                           MatrixTypes.TRANSFORM_IS_UNKNOWN);
        }
예제 #25
0
        void DrawRotatedWithMatrices(SKCanvas canvas, SKPath path, SKPaint fill, SKPaint outline, ChartData item, float degrees, int cx, int cy)
        {
            var identity  = SKMatrix.CreateIdentity();
            var translate = SKMatrix.CreateTranslation(-cx, -cy);
            var rotate    = SKMatrix.CreateRotationDegrees(degrees);

            //angleBox.Text = degrees.ToString();
            var translate2 = SKMatrix.CreateTranslation(cx, cy);

            SKMatrix.PostConcat(ref identity, translate);
            SKMatrix.PostConcat(ref identity, rotate);
            SKMatrix.PostConcat(ref identity, translate2);


            path.Transform(identity);
            canvas.DrawPath(path, fill);
            canvas.DrawPath(path, outline);
        }
예제 #26
0
        public void Translate(float elementTranslationX, float elementTranslationY, MatrixOrder append)
        {
            var main = new SKMatrix(M11, M12, OffsetX, M21, M22, OffsetY, 0, 0, 1);

            var tra = SKMatrix.MakeTranslation(elementTranslationX, elementTranslationY);

            if (append == MatrixOrder.Prepend)
            {
                SKMatrix.PreConcat(ref main, tra);
            }
            else
            {
                SKMatrix.PostConcat(ref main, tra);
            }

            this.SetMatrix(main.ScaleX, main.SkewX, main.SkewY, main.ScaleY, main.TransX, main.TransY,
                           MatrixTypes.TRANSFORM_IS_UNKNOWN);
        }
예제 #27
0
        private void drawSideUzor(int i, SKCanvas canvas, float width, float height)
        {
            update_C_Parameter();

            // left side:
            SKMatrix matrix         = SKMatrix.Identity;
            SKMatrix previousMatrix = canvas.TotalMatrix;
            int      uzorCenterX    = this.PixelSize * this.sideUzorPainter.Data.FieldSize / 2;
            int      uzorLeftShift  = this.PixelSize * this.Data.UzorElements[0].FieldSize / 2; // must be equal to one of the central Uzor-size;

            matrix.TransX = this.sceneCenterX - this.Data.B * this.minimalStepSize - uzorCenterX - uzorLeftShift;

            int uzorCenterY = uzorCenterX; // Uzor is square object

            float phaseShift = Data.A * minimalStepSize / 2;

            matrix.TransY  = i * Data.A * minimalStepSize - uzorCenterY + phaseShift;
            matrix.TransY += this.sceneCenterY;

            SKMatrix.PostConcat(ref matrix, canvas.TotalMatrix);

            canvas.SetMatrix(matrix);
            sideUzorPainter.DrawUzor(this.PixelSize, canvas, width, height, Direction.ToRight);

            canvas.SetMatrix(previousMatrix);

            // right side:
            SKMatrix previousMatrix2 = canvas.TotalMatrix;

            matrix = SKMatrix.Identity;
            int uzorRightShift = this.PixelSize * (this.Data.UzorElements[0].FieldSize / 2 - this.sideUzorPainter.Data.FieldSize / 2);

            matrix.TransX  = this.sceneCenterX + this.Data.B * this.minimalStepSize + uzorRightShift;
            matrix.TransY  = i * Data.A * minimalStepSize - uzorCenterY + phaseShift;
            matrix.TransY += this.sceneCenterY;

            SKMatrix.PostConcat(ref matrix, canvas.TotalMatrix);

            canvas.SetMatrix(matrix);
            sideUzorPainter.DrawUzor(this.PixelSize, canvas, width, height, Direction.ToLeft);

            canvas.SetMatrix(previousMatrix2);
        }
예제 #28
0
        private void HandlePan(object sender, PanUpdatedEventArgs e)
        {
            SKPoint panPt = ToUntransformedCanvasPt((float)e.TotalX, (float)e.TotalY);

            switch (e.StatusType)
            {
            case GestureStatus.Started:
                _lastPanPt = panPt;
                break;

            case GestureStatus.Running:
                SKPoint deltaTran = panPt - _lastPanPt;
                _lastPanPt = panPt;
                SKMatrix deltaM = SKMatrix.MakeTranslation(deltaTran.X, deltaTran.Y);
                SKMatrix.PostConcat(ref _m, deltaM);
                _canvasV.InvalidateSurface();
                break;
            }
        }
예제 #29
0
        void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
        {
            SKImageInfo info    = args.Info;
            SKSurface   surface = args.Surface;
            SKCanvas    canvas  = surface.Canvas;

            canvas.Clear();

            // Find center of canvas
            float xCenter = info.Width / 2;
            float yCenter = info.Height / 2;

            // Translate center to origin
            SKMatrix matrix = SKMatrix.MakeTranslation(-xCenter, -yCenter);

            // Use 3D matrix for 3D rotations and perspective
            SKMatrix44 matrix44 = SKMatrix44.CreateIdentity();

            matrix44.PostConcat(SKMatrix44.CreateRotationDegrees(1, 0, 0, (float)xRotateSlider.Value));
            matrix44.PostConcat(SKMatrix44.CreateRotationDegrees(0, 1, 0, (float)yRotateSlider.Value));
            matrix44.PostConcat(SKMatrix44.CreateRotationDegrees(0, 0, 1, (float)zRotateSlider.Value));

            SKMatrix44 perspectiveMatrix = SKMatrix44.CreateIdentity();

            perspectiveMatrix[3, 2] = -1 / (float)depthSlider.Value;
            matrix44.PostConcat(perspectiveMatrix);

            // Concatenate with 2D matrix
            SKMatrix.PostConcat(ref matrix, matrix44.Matrix);

            // Translate back to center
            SKMatrix.PostConcat(ref matrix,
                                SKMatrix.MakeTranslation(xCenter, yCenter));

            // Set the matrix and display the bitmap
            canvas.SetMatrix(matrix);
            float xBitmap = xCenter - bitmap.Width / 2;
            float yBitmap = yCenter - bitmap.Height / 2;

            canvas.DrawBitmap(bitmap, xBitmap, yBitmap);
        }
예제 #30
0
        public static SKMatrix CaculateOneFingerDraggedMatrix(SKPoint prevPoint, SKPoint curPoint, SKPoint pivotPoint, TouchManipulationMode mode)
        {
            if (mode == TouchManipulationMode.None)
            {
                return(SKMatrix.CreateIdentity());
            }

            SKMatrix touchMatrix = SKMatrix.CreateIdentity();
            SKPoint  delta       = curPoint - prevPoint;

            if (mode == TouchManipulationMode.ScaleDualRotate)  // One-finger rotation
            {
                SKPoint oldVector = prevPoint - pivotPoint;
                SKPoint newVector = curPoint - pivotPoint;

                // Avoid rotation if fingers are too close to center
                if (Magnitude(newVector) > 25 && Magnitude(oldVector) > 25)
                {
                    float prevAngle = (float)Math.Atan2(oldVector.Y, oldVector.X);
                    float newAngle  = (float)Math.Atan2(newVector.Y, newVector.X);

                    // Calculate rotation matrix
                    float angle = newAngle - prevAngle;
                    touchMatrix = SKMatrix.CreateRotation(angle, pivotPoint.X, pivotPoint.Y);

                    // Effectively rotate the old vector
                    float magnitudeRatio = Magnitude(oldVector) / Magnitude(newVector);
                    oldVector.X = magnitudeRatio * newVector.X;
                    oldVector.Y = magnitudeRatio * newVector.Y;

                    // Recalculate delta
                    delta = newVector - oldVector;
                }
            }

            // Multiply the rotation matrix by a translation matrix
            touchMatrix = touchMatrix.PostConcat(SKMatrix.CreateTranslation(delta.X, delta.Y));

            return(touchMatrix);
        }