Selaa lähdekoodia

fix(slur): Slurs avoid note collision (#802)

Fix reference issue with variables. Slurs now avoid colliding with notes properly

Co-authored-by: Justin Litten <justin@jlitten-laptop.WORKGROUP>
fredmeister77 5 vuotta sitten
vanhempi
commit
18397f2be6
3 muutettua tiedostoa jossa 168 lisäystä ja 9 poistoa
  1. 1 0
      demo/index.js
  2. 17 9
      src/MusicalScore/Graphical/GraphicalSlur.ts
  3. 150 0
      test/data/Slurtest_highNotes.musicxml

+ 1 - 0
demo/index.js

@@ -43,6 +43,7 @@ import * as svg2pdf from '../node_modules/svg2pdf.js/dist/svg2pdf.min';
             "OSMD Function Test - System and Page Breaks": "OSMD_Function_Test_System_and_Page_Breaks_4_pages.mxl",
             "OSMD Function Test - Tabulature": "OSMD_Function_Test_Tabulature_hayden_study_1.mxl",
             "OSMD Function Test - Tremolo": "OSMD_Function_Test_Tremolo_2bars.musicxml",
+            "OSMD Function Test - High Slur Test": "Slurtest_highNotes.musicxml",
             "Schubert, F. - An Die Musik": "Schubert_An_die_Musik.xml",
             "Actor, L. - Prelude (Large Sample, loading time)": "ActorPreludeSample.xml",
             "Anonymous - Saltarello": "Saltarello.mxl",

+ 17 - 9
src/MusicalScore/Graphical/GraphicalSlur.ts

@@ -181,11 +181,14 @@ export class GraphicalSlur extends GraphicalCurve {
 
             // calculate tangent Lines Angles
                 // (using the calculated Slopes and the Ratio from the IntersectionPoint's distance to the MaxPoint in the SkyLine)
-            const leftAngle: number = minAngle;
-            const rightAngle: number = -minAngle;
+            let leftAngle: number = minAngle;
+            let rightAngle: number = -minAngle;
             // if the calculated Slopes (left and right) are equal, then Angles have fixed values
             if (!sameSlope) {
-                this.calculateAngles(leftAngle, rightAngle, leftLineSlope, rightLineSlope, maxAngle);
+                const result: {leftAngle: number, rightAngle: number} =
+                    this.calculateAngles(minAngle, leftLineSlope, rightLineSlope, maxAngle);
+                leftAngle = result.leftAngle;
+                rightAngle = result.rightAngle;
             }
 
             // calculate Curve's Control Points
@@ -322,11 +325,14 @@ export class GraphicalSlur extends GraphicalCurve {
 
             // calculate tangent Lines Angles
             // (using the calculated Slopes and the Ratio from the IntersectionPoint's distance to the MaxPoint in the SkyLine)
-            const leftAngle: number = minAngle;
-            const rightAngle: number = -minAngle;
+            let leftAngle: number = minAngle;
+            let rightAngle: number = -minAngle;
             // if the calculated Slopes (left and right) are equal, then Angles have fixed values
             if (!sameSlope) {
-                this.calculateAngles(leftAngle, rightAngle, leftLineSlope, rightLineSlope, maxAngle);
+                const result: {leftAngle: number, rightAngle: number} =
+                    this.calculateAngles(minAngle, leftLineSlope, rightLineSlope, maxAngle);
+                leftAngle = result.leftAngle;
+                rightAngle = result.rightAngle;
             }
 
             // calculate Curve's Control Points
@@ -814,7 +820,8 @@ export class GraphicalSlur extends GraphicalCurve {
      * @param rightLineSlope
      * @param maxAngle
      */
-    private calculateAngles(leftAngle: number, rightAngle: number, leftLineSlope: number, rightLineSlope: number, maxAngle: number): void {
+    private calculateAngles(minAngle: number, leftLineSlope: number, rightLineSlope: number, maxAngle: number):
+    {leftAngle: number, rightAngle: number} {
         // calculate Angles from the calculated Slopes, adding also a given angle
         const angle: number = 20;
 
@@ -833,8 +840,9 @@ export class GraphicalSlur extends GraphicalCurve {
         }
 
         // +/- 80 is the max/min allowed Angle
-        leftAngle = Math.min(Math.max(leftAngle, calculatedLeftAngle), maxAngle);
-        rightAngle = Math.max(Math.min(rightAngle, calculatedRightAngle), -maxAngle);
+        const leftAngle: number = Math.min(Math.max(minAngle, calculatedLeftAngle), maxAngle);
+        const rightAngle: number = Math.max(Math.min(-minAngle, calculatedRightAngle), -maxAngle);
+        return {"leftAngle": leftAngle, "rightAngle": rightAngle};
     }
 
     private static degreesToRadiansFactor: number = Math.PI / 180;

+ 150 - 0
test/data/Slurtest_highNotes.musicxml

@@ -0,0 +1,150 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE score-partwise PUBLIC "-//Recordare//DTD MusicXML 3.1 Partwise//EN" "http://www.musicxml.org/dtds/partwise.dtd">
+<score-partwise version="3.1">
+  <work>
+    <work-title>Title</work-title>
+    </work>
+  <identification>
+    <creator type="composer">Composer</creator>
+    <encoding>
+      <software>MuseScore 3.0.2</software>
+      <encoding-date>2020-06-19</encoding-date>
+      <supports element="accidental" type="yes"/>
+      <supports element="beam" type="yes"/>
+      <supports element="print" attribute="new-page" type="yes" value="yes"/>
+      <supports element="print" attribute="new-system" type="yes" value="yes"/>
+      <supports element="stem" type="yes"/>
+      </encoding>
+    </identification>
+  <defaults>
+    <scaling>
+      <millimeters>7.05556</millimeters>
+      <tenths>40</tenths>
+      </scaling>
+    <page-layout>
+      <page-height>1683.36</page-height>
+      <page-width>1190.88</page-width>
+      <page-margins type="even">
+        <left-margin>56.6929</left-margin>
+        <right-margin>56.6929</right-margin>
+        <top-margin>56.6929</top-margin>
+        <bottom-margin>113.386</bottom-margin>
+        </page-margins>
+      <page-margins type="odd">
+        <left-margin>56.6929</left-margin>
+        <right-margin>56.6929</right-margin>
+        <top-margin>56.6929</top-margin>
+        <bottom-margin>113.386</bottom-margin>
+        </page-margins>
+      </page-layout>
+    <word-font font-family="FreeSerif" font-size="10"/>
+    <lyric-font font-family="FreeSerif" font-size="11"/>
+    </defaults>
+  <credit page="1">
+    <credit-words default-x="1134.19" default-y="1501.67" justify="right" valign="bottom" font-size="12">Composer</credit-words>
+    </credit>
+  <credit page="1">
+    <credit-words default-x="595.44" default-y="1626.67" justify="center" valign="top" font-size="24">Title</credit-words>
+    </credit>
+  <part-list>
+    <score-part id="P1">
+      <part-name>Piano</part-name>
+      <part-abbreviation>Pno.</part-abbreviation>
+      <score-instrument id="P1-I1">
+        <instrument-name>Piano</instrument-name>
+        </score-instrument>
+      <midi-device id="P1-I1" port="1"></midi-device>
+      <midi-instrument id="P1-I1">
+        <midi-channel>1</midi-channel>
+        <midi-program>1</midi-program>
+        <volume>78.7402</volume>
+        <pan>0</pan>
+        </midi-instrument>
+      </score-part>
+    </part-list>
+  <part id="P1">
+    <measure number="1" width="258.83">
+      <print>
+        <system-layout>
+          <system-margins>
+            <left-margin>0.00</left-margin>
+            <right-margin>626.91</right-margin>
+            </system-margins>
+          <top-system-distance>195.00</top-system-distance>
+          </system-layout>
+        </print>
+      <attributes>
+        <divisions>1</divisions>
+        <key>
+          <fifths>0</fifths>
+          </key>
+        <time>
+          <beats>4</beats>
+          <beat-type>4</beat-type>
+          </time>
+        <clef>
+          <sign>G</sign>
+          <line>2</line>
+          </clef>
+        </attributes>
+      <note default-x="69.27" default-y="-10.00">
+        <pitch>
+          <step>D</step>
+          <octave>5</octave>
+          </pitch>
+        <duration>2</duration>
+        <voice>1</voice>
+        <type>half</type>
+        <stem>down</stem>
+        <notations>
+          <slur type="start" placement="above" number="1"/>
+          </notations>
+        </note>
+      <note default-x="153.01" default-y="25.00">
+        <pitch>
+          <step>D</step>
+          <octave>6</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>quarter</type>
+        <stem>down</stem>
+        </note>
+      <note default-x="205.12" default-y="15.00">
+        <pitch>
+          <step>B</step>
+          <octave>5</octave>
+          </pitch>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>quarter</type>
+        <stem>down</stem>
+        </note>
+      </measure>
+    <measure number="2" width="191.76">
+      <note default-x="10.36" default-y="-20.00">
+        <pitch>
+          <step>B</step>
+          <octave>4</octave>
+          </pitch>
+        <duration>3</duration>
+        <voice>1</voice>
+        <type>half</type>
+        <dot/>
+        <stem>down</stem>
+        <notations>
+          <slur type="stop" number="1"/>
+          </notations>
+        </note>
+      <note>
+        <rest/>
+        <duration>1</duration>
+        <voice>1</voice>
+        <type>quarter</type>
+        </note>
+      <barline location="right">
+        <bar-style>light-heavy</bar-style>
+        </barline>
+      </measure>
+    </part>
+  </score-partwise>