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); }
public static SKMatrix CaculateTwoFingerDraggedMatrix(SKPoint prevPoint, SKPoint curPoint, SKPoint pivotPoint, TouchManipulationMode mode) { SKMatrix touchMatrix = SKMatrix.CreateIdentity(); SKPoint oldVector = prevPoint - pivotPoint; SKPoint newVector = curPoint - 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)) { touchMatrix = touchMatrix.PostConcat(SKMatrix.CreateScale(scaleX, scaleY, pivotPoint.X, pivotPoint.Y)); } return(touchMatrix); }