/// <summary> /// Returns the inverse rotation matrix for the given node and the current angle. /// </summary> private Matrix2D GetInverseRotationMatrix(INode node) { var center = node.Layout.GetCenter(); if (!(center.Equals(inverseMatrixCenter)) || Angle != inverseMatrixAngle) { inverseMatrix.Reset(); inverseMatrix.Rotate(CachingOrientedRectangle.ToRadians(-Angle), center); inverseMatrixCenter = center; inverseMatrixAngle = Angle; } return(inverseMatrix); }
/// <summary> /// Snaps the angle to the rotation angles of other nodes and the coordinate axes. /// </summary> /// <remarks> /// Angles near such an angle are replaced with this angle. /// </remarks> private double SnapAngle(IInputModeContext context, double angle) { // Check for disabled snapping var snapContext = context.Lookup <SnapContext>(); if (snapContext != null && !snapContext.Enabled) { return(angle); } // Same angle snapping if (SnapToSameAngleDelta > 0 && nodeAngles != null) { // Find the first angle that is sufficiently similar var candidate = nodeAngles.Where(na => CachingOrientedRectangle.NormalizeAngle(Math.Abs(na.Item1 - angle)) < SnapToSameAngleDelta).OrderBy(na => na.Item1).FirstOrDefault(); if (candidate != null) { // Add highlight to every matching node var canvas = (GraphControl)context.CanvasControl; if (sameAngleHighlightedNodes != candidate.Item2) { ClearSameAngleHighlights(context); } foreach (var matchingNode in candidate.Item2) { canvas.HighlightIndicatorManager.AddHighlight(matchingNode); } sameAngleHighlightedNodes = candidate.Item2; return(candidate.Item1); } ClearSameAngleHighlights(context); } if (SnapDelta <= 0.0 || SnapStep == 0) { return(angle); } var mod = Math.Abs(angle % SnapStep); return((mod < SnapDelta || mod > SnapStep - SnapDelta) ? SnapStep * Math.Round(angle / SnapStep) : angle); }
/// <summary> /// Returns the 'snapped' vector for the given up vector. /// </summary> /// <remarks> /// If the vector is almost horizontal or vertical, this method returns the exact horizontal /// or vertical up vector instead. /// </remarks> private static double CalculateAngle(PointD upVector) { return(CachingOrientedRectangle.NormalizeAngle(-(Math.Atan2(upVector.Y, upVector.X) / Math.PI * 180 + 90))); }