]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/beam.cc
patch::: 0.0.68pre.jcn1: Re: patsen?
[lilypond.git] / lily / beam.cc
index 3d16d96518d54b2d0416a069e46324c4880d6d01..d0b0079692411028520408b3e82ba771d4979f9e 100644 (file)
@@ -12,6 +12,9 @@
   
 */
 
+#include <math.h>
+
+#include "p-col.hh"
 #include "varray.hh"
 #include "proto.hh"
 #include "dimen.hh"
@@ -21,7 +24,6 @@
 #include "symbol.hh"
 #include "molecule.hh"
 #include "leastsquares.hh"
-#include "p-col.hh"
 #include "stem.hh"
 #include "paper-def.hh"
 #include "lookup.hh"
 
 struct Stem_info {
     Real x;
-    Real idealy;
-    Real miny;
-    int no_beams;
+    int dir_i_;
+    Real idealy_f_;
+    Real miny_f_;
+    int beams_i_;
 
-    
     Stem_info(){}
     Stem_info(Stem const *);
 };
@@ -43,17 +45,52 @@ struct Stem_info {
 Stem_info::Stem_info(Stem const *s)
 {
     x = s->hpos_f();
-    int dir = s->dir_i_;
-    idealy  = dir * s->stem_end_f();
-    miny = dir * s->stem_start_f() + 2;        // ugh
-    assert(miny <= idealy);
+    dir_i_ = s->dir_i_;
+    beams_i_ = intlog2( s->flag_i_ ) - 2;
+
+    /*
+     [todo] 
+         * get algorithm
+        * runtime
+
+     Breitkopf + H\"artel:
+         miny_f_ = interline + #beams * interbeam
+        ideal8 = 2 * interline + interbeam
+        ideal16,32,64,128 = 1.5 * interline + #beams * interbeam
+
+     * B\"arenreiter:
+         miny_f_ = interline + #beams * interbeam
+        ideal8,16 = 2 interline + #beams * interbeam
+        ideal32,64,128 = 1.5 interline + #beams * interbeam
+         
+     */
+
+    Real notehead_y = s->paper()->interline_f();
+    // huh? why do i need the / 2
+//    Real interbeam_f = s->paper()->interbeam_f();
+    Real interbeam_f = s->paper()->interbeam_f() / 2;
+    Real interline_f = s->paper()->interline_f();
+           
+    /* well eh, huh?
+    idealy_f_  = dir_i_ * s->stem_start_f() + beams_i_ * interbeam_f; 
+    if ( beams_i_ < 3 )
+       idealy_f_ += 2 * interline_f;
+    else
+       idealy_f_ += 1.5 * interline_f;
+    */
+
+    idealy_f_  = dir_i_ * s->stem_end_f();
+
+    miny_f_ = dir_i_ * s->stem_start_f() + notehead_y + beams_i_ * interbeam_f;
+
+    idealy_f_ =  miny_f_ >? idealy_f_;
+//    assert(miny_f_ <= idealy_f_);
 }
 
 
 /* *************** */
 
 
-
 Offset
 Beam::center()const
 {
@@ -79,16 +116,30 @@ Beam::add(Stem*s)
 void
 Beam::set_default_dir()
 {
-    int dirs_single = 0, dirs_chord = 0;
+    int up = 0, down = 0;
+    int up_count = 0, down_count = 0;
+
     for (int i=0; i <stems.size(); i++) {
        Stem *sl = stems[i];
-       if (sl->chord_b())
-           dirs_chord += sl->get_default_dir();
-       else
-           dirs_single += sl->get_center_distance();
+       int cur_down = sl->get_center_distance_from_top();
+       int cur_up = sl->get_center_distance_from_bottom();
+       if (cur_down) {
+           down += cur_down;
+           down_count++;
+       }
+       if (cur_up) {
+           up += cur_up;
+           up_count++;
+       }
     }
-    dirs_single = -sign(dirs_single);
-    dir_i_ = (dirs_single + dirs_chord > 0) ? 1 : -1;
+    if (!down)
+       down_count = 1;
+    if (!up)
+       up_count = 1;
+
+    // the following relation is equal to
+    //        up / up_count > down / down_count
+    dir_i_ = (up * down_count > down * up_count) ? 1 : -1;
 
    for (int i=0; i <stems.size(); i++) {
        Stem *sl = stems[i];
@@ -103,7 +154,7 @@ void
 Beam::solve_slope()
 {
     Array<Stem_info> sinfo;
-  for (int j=0; j <stems.size(); j++) {
+    for (int j=0; j <stems.size(); j++) {
        Stem *i = stems[j];
 
        i->set_default_extents();
@@ -117,21 +168,23 @@ Beam::solve_slope()
     Least_squares l;
     for (int i=0; i < sinfo.size(); i++) {
        sinfo[i].x -= leftx;
-       l.input.push(Offset(sinfo[i].x, sinfo[i].idealy));
+       l.input.push(Offset(sinfo[i].x, sinfo[i].idealy_f_));
     }
 
     l.minimise(slope, left_pos);
     Real dy = 0.0;
     for (int i=0; i < sinfo.size(); i++) {
        Real y = sinfo[i].x * slope + left_pos;
-       Real my = sinfo[i].miny;
+       Real my = sinfo[i].miny_f_;
 
        if (my - y > dy)
            dy = my -y; 
     }
     left_pos += dy;
     left_pos *= dir_i_;    
+
     slope *= dir_i_;
+    slope = 0.6 * tanh(slope);  // damping
 
                                // ugh
     Real sl = slope*paper()->internote_f();
@@ -195,8 +248,6 @@ Beam::set_grouping(Rhythmic_grouping def, Rhythmic_grouping cur)
 void
 Beam::do_pre_processing()
 {
-    left_col_l_ = stems[0]   ->pcol_l_;
-    right_col_l_ = stems.top()->pcol_l_;    
     assert(stems.size()>1);
     if (!dir_i_)
        set_default_dir();
@@ -219,7 +270,8 @@ Beam::stem_beams(Stem *here, Stem *next, Stem *prev)const
 {
     assert( !next || next->hpos_f() > here->hpos_f()  );
     assert( !prev || prev->hpos_f() < here->hpos_f()  );
-    Real dy=paper()->internote_f()*2;
+//    Real dy=paper()->internote_f()*2;
+    Real dy = paper()->interbeam_f();
     Real stemdx = paper()->rule_thickness();
     Real sl = slope*paper()->internote_f();
     paper()->lookup_l()->beam(sl, 20 PT);
@@ -239,7 +291,7 @@ Beam::stem_beams(Stem *here, Stem *next, Stem *prev)const
        a.translate(Offset (-w, -w * sl));
        for (int j = 0; j  < lhalfs; j++) {
            Atom b(a);
-           b.translate(Offset(0, -dir_i_ * dy * (lwholebeams+j)));
+           b.translate_y( -dir_i_ * dy * (lwholebeams+j));
            leftbeams.add( b );
        }
     }
@@ -254,7 +306,7 @@ Beam::stem_beams(Stem *here, Stem *next, Stem *prev)const
        int j = 0;
        for (; j  < rwholebeams; j++) {
            Atom b(a);
-           b.translate(Offset(0, -dir_i_ * dy * j));
+           b.translate_y( -dir_i_ * dy * j);
            rightbeams.add( b ); 
        }
 
@@ -264,7 +316,7 @@ Beam::stem_beams(Stem *here, Stem *next, Stem *prev)const
        
        for (; j  < rwholebeams + rhalfs; j++) {
            Atom b(a);
-           b.translate(Offset(0, -dir_i_ * dy * j));
+           b.translate_y( -dir_i_ * dy * j);
            rightbeams.add(b ); 
        }
        
@@ -277,9 +329,15 @@ Beam::stem_beams(Stem *here, Stem *next, Stem *prev)const
 Molecule*
 Beam::brew_molecule_p() const 
 {
-    Molecule *out=0;
-    Real inter=paper()->internote_f();
-    out = new Molecule;
+    /*
+      [todo]
+      the y of the (start) of the beam should be quantisized,
+      so that no stafflines appear just in between two beam-flags
+     */
+    Molecule *mol_p = new Molecule;
+    // huh? inter-what
+//    Real inter_f = paper()->interbeam_f();
+    Real inter_f = paper()->internote_f();
     Real x0 = stems[0]->hpos_f();
     for (int j=0; j <stems.size(); j++) {
        Stem *i = stems[j];
@@ -288,14 +346,15 @@ Beam::brew_molecule_p() const
 
        Molecule sb = stem_beams(i, next, prev);
        Real  x = i->hpos_f()-x0;
-       sb.translate(Offset(x, (x * slope  + left_pos)* inter));
-       out->add(sb);
+       sb.translate(Offset(x, (x * slope  + left_pos)* inter_f));
+       mol_p->add(sb);
     }
-    out->translate(Offset(x0 - left_col_l_->hpos,0));
-    return out;
+    mol_p->translate_x(x0 - left_col_l_->hpos);
+    return mol_p;
 }
 
 IMPLEMENT_STATIC_NAME(Beam);
+IMPLEMENT_IS_TYPE_B1(Beam, Spanner);
 
 void
 Beam::do_print()const