Exemple #1
0
        internal LayoutLine GetStringBoundaryLine(SIString str, FingerboardSide dir)
        {
            LayoutLine boundary = null;

            if (dir == FingerboardSide.Bass)
            {
                boundary = VisualElements.OfType <StringCenter>().FirstOrDefault(c => c.Right.Index == str.Index);
            }
            else
            {
                boundary = VisualElements.OfType <StringCenter>().FirstOrDefault(c => c.Left.Index == str.Index);
            }

            if (boundary == null)
            {
                return(VisualElements.OfType <FingerboardSideEdge>().First(e => e.Side == dir));
            }

            return(boundary);
        }
Exemple #2
0
 public IEnumerable <T> GetElements <T>() where T : VisualElement
 {
     return(VisualElements.OfType <T>());
 }
Exemple #3
0
 public IEnumerable <T> GetElements <T>(Predicate <T> predicate) where T : VisualElement
 {
     return(VisualElements.OfType <T>().Where(x => predicate(x)));
 }
Exemple #4
0
 public T GetElement <T>(Predicate <T> predicate) where T : VisualElement
 {
     return(VisualElements.OfType <T>().FirstOrDefault(x => predicate(x)));
 }
Exemple #5
0
        private void FinishFingerboardShape()
        {
            var trebleSideEdge = VisualElements.OfType <FingerboardSideEdge>().First(e => e.Side == FingerboardSide.Treble);
            var bassSideEdge   = VisualElements.OfType <FingerboardSideEdge>().First(e => e.Side == FingerboardSide.Bass);
            var trebleNutFret  = VisualElements.OfType <FretLine>().First(f => f.IsNut && f.Strings.Contains(FirstString));
            var bassNutFret    = VisualElements.OfType <FretLine>().First(f => f.IsNut && f.Strings.Contains(LastString));

            //create inward fingerboard edges from nut
            if (!Strings.AllEqual(s => s.StartingFret))
            {
                foreach (var str in Strings)
                {
                    if (str.Next != null && str.StartingFret != str.Next.StartingFret)
                    {
                        var nut1 = VisualElements.OfType <FretLine>().First(f => f.IsNut && f.Strings.Contains(str));
                        var nut2 = VisualElements.OfType <FretLine>().First(f => f.IsNut && f.Strings.Contains(str.Next));
                        AddVisualElement(new FingerboardEdge(nut1.Points.First(), nut2.Points.Last())
                        {
                            IsSideEdge = true
                        });

                        //var center = GetStringBoundaryLine(str, FingerboardSide.Bass) as StringCenter;
                        //var p1 = center.GetRelativePoint(str.LayoutLine, str.LayoutLine.P1);
                        //var p2 = center.GetRelativePoint(str.Next.LayoutLine, str.Next.LayoutLine.P1);
                        //AddVisualElement(new FingerboardEdge(p1, p2) { IsSideEdge = true });
                    }
                }
            }

            var trebSideNutInter = PointM.Empty;

            if (trebleNutFret.Intersects(trebleSideEdge, out trebSideNutInter))
            {
                trebleSideEdge.P1 = trebSideNutInter;
            }

            var bassSideNutInter = PointM.Empty;

            if (bassNutFret.Intersects(bassSideEdge, out bassSideNutInter))
            {
                bassSideEdge.P1 = bassSideNutInter;
            }

            trebleSideEdge.RealEnd = trebleSideEdge.P2;
            bassSideEdge.RealEnd   = bassSideEdge.P2;

            var trebleLastFret = VisualElements.OfType <FretLine>().First(f => f.FretIndex == FirstString.NumberOfFrets && f.Strings.Contains(FirstString));
            var bassLastFret   = VisualElements.OfType <FretLine>().First(f => f.FretIndex == LastString.NumberOfFrets && f.Strings.Contains(LastString));

            PointM trebleEndPoint = trebleLastFret.Points.Last();
            PointM bassEndPoint   = bassLastFret.Points.First();

            if (!Margins.LastFret.IsEmpty)
            {
                trebleEndPoint += trebleSideEdge.Direction * Margins.LastFret;
                bassEndPoint   += bassSideEdge.Direction * Margins.LastFret;
            }

            //split physical from virtual fingerboard
            var virtualTrebleEdge = AddVisualElement(new LayoutLine(trebleEndPoint, trebleSideEdge.P2, VisualElementType.FingerboardContinuation));
            var virtualBassEdge   = AddVisualElement(new LayoutLine(bassEndPoint, bassSideEdge.P2, VisualElementType.FingerboardContinuation));

            trebleSideEdge.P2 = virtualTrebleEdge.P1;
            bassSideEdge.P2   = virtualBassEdge.P1;

            if (NumberOfStrings > 1)
            {
                var bridgeLine = new LayoutPolyLine(Strings.Select(s => s.LayoutLine.P2), VisualElementType.BridgeLine);
                VisualElements.Add(bridgeLine);

                var bridgeTrebleInter = PointM.Empty;
                if (bridgeLine.Intersects(virtualTrebleEdge, out bridgeTrebleInter))
                {
                    virtualTrebleEdge.P2 = bridgeTrebleInter;
                }

                var bridgeBassInter = PointM.Empty;
                if (bridgeLine.Intersects(virtualBassEdge, out bridgeBassInter))
                {
                    virtualBassEdge.P2 = bridgeBassInter;
                }
            }

            if (trebleLastFret.Strings.Count() == NumberOfStrings && trebleLastFret.IsStraight && trebleLastFret.FretIndex == MaximumFret)
            {
                AddVisualElement(new FingerboardEdge(bassSideEdge.P2, trebleSideEdge.P2));
            }
            else if (!Margins.LastFret.IsEmpty)
            {
                var fretLines  = VisualElements.OfType <FretLine>();
                var edgePoints = new List <PointM>();

                for (int i = NumberOfStrings - 1; i >= 0; i--)
                {
                    var strLastFret = fretLines.First(fl => fl.FretIndex == Strings[i].NumberOfFrets && fl.Strings.Contains(Strings[i]));
                    var trebleSide  = GetStringBoundaryLine(Strings[i], FingerboardSide.Treble);
                    var bassSide    = GetStringBoundaryLine(Strings[i], FingerboardSide.Bass);
                    var pt1         = PointM.Empty;
                    var pt2         = PointM.Empty;

                    if (!strLastFret.Intersects(bassSide, out pt1))
                    {
                        pt1 = strLastFret.Points.First();
                    }

                    if (!strLastFret.Intersects(trebleSide, out pt2))
                    {
                        pt2 = strLastFret.Points.Last();
                    }

                    pt1 += bassSide.Direction * Margins.LastFret;
                    pt2 += trebleSide.Direction * Margins.LastFret;

                    edgePoints.Add(pt1);
                    edgePoints.Add(pt2);
                }

                //edgePoints.RemoveAll(p => p.IsEmpty);
                edgePoints = edgePoints.Distinct().ToList();
                var fretboardEdge = AddVisualElement(new FingerboardEdge(edgePoints));
                //fretboardEdge.InterpolateSpline();
            }

            var fingerboardEnds = VisualElements.OfType <FingerboardEdge>();

            var trebleLine = FirstString.LayoutLine;

            foreach (var end in fingerboardEnds)
            {
                if (end.Intersects(trebleLine, out PointM inter, false))
                {
                    AddVisualElement(new LayoutLine(trebleLine.P1, inter, VisualElementType.FingerboardMargin));
                    break;
                }
            }

            if (LastString != FirstString)
            {
                var bassLine = LastString.LayoutLine;

                foreach (var end in fingerboardEnds)
                {
                    if (end.Intersects(bassLine, out PointM inter, false))
                    {
                        AddVisualElement(new LayoutLine(bassLine.P1, inter, VisualElementType.FingerboardMargin));
                        break;
                    }
                }
            }
        }
Exemple #6
0
 internal StringCenter GetStringsCenter(SIString left, SIString right)
 {
     return(VisualElements.OfType <StringCenter>().FirstOrDefault(c =>
                                                                  (left.Index == c.Right.Index || left.Index == c.Left.Index) &&
                                                                  (right.Index == c.Right.Index || right.Index == c.Left.Index)));
 }
Exemple #7
0
        private void LayoutStrings(Measure[] nutStringPos, Measure[] bridgeStringPos)
        {
            var stringLines = VisualElements.OfType <StringLine>();

            if (NumberOfStrings == 1)
            {
                ConstructString(Strings[0], nutStringPos[0], bridgeStringPos[0]);
            }
            else if (ScaleLengthMode != ScaleLengthType.Multiple)
            {
                var trebleStr = ConstructString(Strings[0], nutStringPos[0], bridgeStringPos[0]);
                var bassStr   = ConstructString(Strings[NumberOfStrings - 1], nutStringPos[NumberOfStrings - 1], bridgeStringPos[NumberOfStrings - 1]);

                var maxHeight = Measure.Max(trebleStr.Bounds.Height, bassStr.Bounds.Height);
                AdjustStringVerticalPosition(trebleStr, maxHeight);
                AdjustStringVerticalPosition(bassStr, maxHeight);

                var nutLine     = Line.FromPoints(trebleStr.P1.ToVector(), bassStr.P1.ToVector());
                var bridgeLine  = Line.FromPoints(trebleStr.P2.ToVector(), bassStr.P2.ToVector());
                var twelfthFret = new LayoutLine(PointM.Average(trebleStr.P1, trebleStr.P2), PointM.Average(bassStr.P1, bassStr.P2));

                //create the remaining strings by distributing them equally between the outer strings
                for (int i = 1; i < NumberOfStrings - 1; i++)
                {
                    var nutPos        = nutLine.GetPointForX(nutStringPos[i].NormalizedValue);
                    var bridgePos     = bridgeLine.GetPointForX(bridgeStringPos[i].NormalizedValue);
                    var createdString = AddVisualElement(new StringLine(Strings[i],
                                                                        PointM.FromVector(nutPos, nutStringPos[i].Unit),
                                                                        PointM.FromVector(bridgePos, bridgeStringPos[i].Unit)));

                    //strings distributed equally between the outer strings (which are tapered/angled) do not have their centers aligned
                    //so we correct the string length (at bridge) so that its center is aligned with the twelfth fret

                    var middle         = createdString.GetIntersection(twelfthFret);
                    var distFromNut    = PointM.Distance(createdString.P1, middle);
                    var distFromBridge = PointM.Distance(createdString.P2, middle);

                    var stringCenterOffset = Measure.Abs(distFromNut - distFromBridge);

                    if (!CompensateFretPositions && stringCenterOffset > Measure.Mm(0.05))
                    {
                        //adjust the end of the string so that it's center is above the 12th fret
                        createdString.P2 = createdString.P1 + (createdString.Direction * distFromNut * 2);
                    }

                    Strings[i].RecalculateLengths();//store the physical length of the string
                }
            }
            else
            {
                for (int i = 0; i < NumberOfStrings; i++)
                {
                    ConstructString(Strings[i], nutStringPos[i], bridgeStringPos[i]);
                }

                //*** Adjust strings position for multiscale
                var maxPerpHeight = Measure.FromNormalizedValue(stringLines.Max(l => l.Bounds.Height.NormalizedValue), UnitOfMeasure.Mm);
                foreach (var strLine in stringLines)
                {
                    AdjustStringVerticalPosition(strLine, maxPerpHeight);
                }
            }

            //calculate starting fret position if different from 0 (nut)
            foreach (var str in Strings)
            {
                if (str.StartingFret != 0)
                {
                    var startingFretPosRatio = GetEqualTemperedFretPosition(str.StartingFret);
                    var stringVector         = str.PlaceFretsRelativeToString ? str.LayoutLine.Direction * -1 : new Vector(0, 1);
                    var startingFretPos      = str.LayoutLine.P2 + (stringVector * str.CalculatedLength * startingFretPosRatio);

                    if (!str.PlaceFretsRelativeToString)
                    {
                        startingFretPos = str.LayoutLine.SnapToLine(startingFretPos, LineSnapDirection.Horizontal);
                    }

                    str.LayoutLine.P1 = startingFretPos;
                    str.RecalculateLengths();
                }
            }

            for (int i = 0; i < NumberOfStrings - 1; i++)
            {
                AddVisualElement(new StringCenter(Strings[i + 1].LayoutLine, Strings[i].LayoutLine));
            }
        }