public PerceptualTime( TupletClass tuplet, LengthClass length, int dots ) { Tuplet = tuplet; Length = length; Dots = dots; }
void LayoutBeams() { var beamsequences = new List <ChordLayout[]>(); foreach (var chord in chords.OrderBy(chord => chord.Duration.Start).OrderByDescending(chord => chord.Duration.Length.Ticks)) { if (chord.Flags != 0) { continue; // already hit } if (chord.Length.Length > LengthClass.Quarter) { var cell = chord.Notes[0].Core.Cell; if (chord.Duration.End < cell.Duration.End) { var train = new List <ChordLayout>(); var last = chord; while (last.Duration.End < cell.Duration.End) { train.Add(last); var candidates = chords .Where(candidate => candidate.Duration.Start == last.Duration.End) .Where(candidate => candidate.Duration.Length < Time.Note_4th) .ToArray(); var bestcandidate = candidates .OrderBy( candidate => candidate.Notes.Min(note => Math.Abs(note.HalfLine - last.Notes.Min(note2 => note2.HalfLine))) ) .FirstOrDefault(); if (bestcandidate == null) { break; } last = bestcandidate; } if (last.Duration.End == cell.Duration.End) { train.Add(last); } if (train.Count > 1) { var Xs = train.Select(item => item.X).ToArray(); var Ys = train.Select(item => item.Notes.Average(note => (float)note.HalfLine)).ToArray(); float m, b; if (!Statistics.LinearRegression(Xs, Ys, out m, out b)) { b = 0; m = 0; } var stemdirection = NoteStemDirection.None; var stemside = NoteStemSide.None; if (train.Average(chordi => chordi.Notes.Average(notei => (float)notei.HalfLine)) >= staff.MiddleHalfLine) { stemdirection = NoteStemDirection.Down; stemside = NoteStemSide.Left; } else { stemdirection = NoteStemDirection.Up; stemside = NoteStemSide.Right; } float stemoffset = 3; if (stemdirection == NoteStemDirection.Down) { stemoffset *= -1; } LengthClass lastlengthclass = LengthClass.Invalid; for (var i = 0; i < train.Count; i++) { var is1 = i == 0; var is2 = i == 1; var item = train[i]; item.StemDirection = stemdirection; item.StemSide = stemside; item.FlagSlope = m; item.LastLengthClass = lastlengthclass; lastlengthclass = item.Length.Length; if (is1) { item.FlagDirection = FlagDirection.Right; item.FlagLength = ToVirtualPX(item.Duration.Length); } else { item.FlagDirection = FlagDirection.Left; item.FlagLength = ToVirtualPX(train[i - 1].Duration.Length); } if (is1 || is2) { item.FlagLength /= 2F; } else { item.Past2nd = true; } item.TiedFlags = item.Length.Length - LengthClass.Quarter; //TODO: also identify which are free flags item.StemStartHalfLines = stemoffset + item.X * m + b; } } else { chord.FreeFlags = chord.Length.Length - LengthClass.Quarter; if (chord.StemDirection == NoteStemDirection.Down) { chord.FlagDirection = FlagDirection.Left; } else { chord.FlagDirection = FlagDirection.Right; } } } else { chord.FreeFlags = chord.Length.Length - LengthClass.Quarter; if (chord.StemDirection == NoteStemDirection.Down) { chord.FlagDirection = FlagDirection.Left; } else { chord.FlagDirection = FlagDirection.Right; } } } } }