/// <summary> /// Returns the type of manipulation that will happen when interacting with the element at the specified point. /// </summary> /// <param name="point">The point to start manipulating.</param> /// <param name="altDown">Whether any alt key is pressed.</param> /// <param name="preview">whether to set the preview manipulation, or the real one.</param> /// <param name="translateOnly">Whether to ignore any special manipulations and only use translate.</param> /// <returns>The manipulation type for the specified point. <c>null</c> if no manipulation would happen /// at this point.</returns> /// <remarks>Manipulation preview is used to show what would be modified on a selected element. We cannot /// keep updating the element manipulation as the mouse moves, but do want to provide a visual indicator.</remarks> public override bool StartManipulating(Point point, bool altDown, bool preview = false, bool translateOnly = false) { SizeF d = point - this.Location; if (d.Length() > this.Radius + 2) { this.PreviewManipulation = null; return(false); } // Scale if mouse over the outter edge. if (Math.Sqrt(Math.Abs(Math.Pow(d.Width, 2) + Math.Pow(d.Height, 2) - Math.Pow(this.Radius, 2))) < 16 && !translateOnly) { this.SetManipulation( new ElementManipulation { Type = ElementManipulationType.Scale, Index = 0, Direction = d.GetUnitVector() }, preview); return(true); } this.SetManipulation( new ElementManipulation { Type = ElementManipulationType.Translate, Index = 0 }, preview); return(true); }
/// <summary> /// Projects <paramref name="toProject"/> onto <paramref name="projectOn"/>. /// </summary> /// <param name="toProject">The speed to project.</param> /// <param name="projectOn">The speed to project on.</param> /// <returns>The projected speed.</returns> public static SizeF ProjectOn(this SizeF toProject, SizeF projectOn) { /* Projecting is easiest on a unit matrix. Therefore we call u the unit matrix of projectOn. * The projection matrix is then: * | ux^2 ux * uy | | ux * uy uy^2 | */ var unitVector = projectOn.GetUnitVector(); var projectionMatrix = new Matrix( unitVector.Width * unitVector.Width, unitVector.Width * unitVector.Height, unitVector.Width * unitVector.Height, unitVector.Height * unitVector.Height, 0, 0); var inputList = new[] { new PointF(toProject.Width, toProject.Height) }; projectionMatrix.TransformVectors(inputList); return(new SizeF(inputList[0].X, inputList[0].Y)); }