/// <summary>
        /// Calculates slur height trying to avoid collisions with stems
        /// </summary>
        /// <param name="note"></param>
        /// <param name="endPoint"></param>
        /// <returns></returns>
        private double DetermineSlurHeight(Note note, Slur slur, SlurInfo slurStartInfo, Point endPoint)
        {
            var notesUnderSlur = note.Staff.EnumerateUntilConditionMet <Note>(note, n => n.Slurs.FirstOrDefault(s => s.Number == slur.Number)?.Type == NoteSlurType.Start, true).ToArray();

            if (notesUnderSlur.Length < 3)
            {
                return(10);
            }

            var notesUnderSlurExclusive = notesUnderSlur.Take(notesUnderSlur.Length - 1).Skip(1);
            var mostExtremePoint        = GetMostExtremePoint(notesUnderSlurExclusive, slurStartInfo.StartPlacement);

            var angle = UsefulMath.BeamAngle(slurStartInfo.StartPoint.X, slurStartInfo.StartPoint.Y, endPoint.X, endPoint.Y);
            var slurYPositionInMostExtremePoint = slurStartInfo.StartPoint.TranslateHorizontallyAndMaintainAngle(angle, mostExtremePoint.X - slurStartInfo.StartPoint.X).Y;
            var mostExtremeYPosition            = mostExtremePoint.Y;

            if (slurStartInfo.StartPlacement == VerticalPlacement.Above && mostExtremeYPosition < slurYPositionInMostExtremePoint)
            {
                return(Math.Abs(mostExtremeYPosition - slurYPositionInMostExtremePoint) + 10);
            }
            if (slurStartInfo.StartPlacement == VerticalPlacement.Below && mostExtremeYPosition > slurYPositionInMostExtremePoint)
            {
                return(Math.Abs(slurYPositionInMostExtremePoint - mostExtremeYPosition) + 10);
            }

            return(10);
        }
        private static Tuple <Point, Point> GetBezierControlPoints(Point start, Point end, VerticalPlacement placement, double height)
        {
            var factor   = placement == VerticalPlacement.Above ? -1 : 1;
            var angle    = UsefulMath.BeamAngle(start.X, start.Y, end.X, end.Y);
            var angle2   = angle + (Math.PI / 2) * factor;
            var distance = Point.Distance(start, end);
            var startPointForControlPoints = start.TranslateByAngleOld(angle2, height);
            var control1 = startPointForControlPoints.TranslateByAngleOld(angle, distance * 0.25);
            var control2 = startPointForControlPoints.TranslateByAngleOld(angle, distance * 0.75);

            return(new Tuple <Point, Point>(control1, control2));
        }
Esempio n. 3
0
 /// <summary>
 /// Calculates beam angle
 /// </summary>
 /// <param name="beamStart">Beam start position</param>
 /// <param name="beamEnd">Beam end position</param>
 /// <returns></returns>
 public static double BeamAngle(Point beamStart, Point beamEnd)
 {
     return(UsefulMath.BeamAngle(beamStart.X, beamStart.Y, beamEnd.X, beamEnd.Y));
 }