]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/slur-bezier-bow.cc
2003 -> 2004
[lilypond.git] / lily / slur-bezier-bow.cc
index 0dc7ba241866effca0137ddb2a4bbe8e59ba5de8..f007d58dae10927ce8e65bb0e70c67f8eb388b0a 100644 (file)
@@ -3,19 +3,73 @@
 
   source file of the GNU LilyPond music typesetter
 
-  (c) 2000  Jan Nieuwenhuizen <janneke@gnu.org>
+  (c) 2000--2004  Jan Nieuwenhuizen <janneke@gnu.org>
 */
 
-#include "debug.hh"
+#include "warn.hh"
 #include "paper-def.hh"
 #include "slur-bezier-bow.hh"
-#include "main.hh"
 
-Slur_bezier_bow::Slur_bezier_bow (Array<Offset> encompass, Direction dir)
-  : Bezier_bow (encompass, dir)
+Slur_bezier_bow::Slur_bezier_bow (Array<Offset> encompass, Direction dir,
+                                 Real h_inf, Real r_0)
 {
+  h_inf_ = h_inf;
+  r_0_ = r_0;
+  alpha_ = 0;
+  dir_ = dir;
+  encompass_ = encompass;
+  to_canonical_form ();
+
+  Real w = encompass_.top ()[X_AXIS] - encompass_[0][X_AXIS];
+  curve_ = slur_shape (w, h_inf, r_0);
+}
+
+Bezier
+Slur_bezier_bow::get_bezier () const
+{
+  Bezier rv = curve_;
+  if (dir_ == DOWN)
+    {
+      rv.scale (1, -1);
+    }
+
+  rv.rotate (alpha_);
+  rv.translate (origin_);
+  
+  return rv;
 }
 
+void
+Slur_bezier_bow::to_canonical_form ()
+{
+  origin_ = encompass_[0];
+  translate (&encompass_, -origin_);
+
+  Offset delta = encompass_.top () - encompass_[0];
+  alpha_ = delta.arg ();
+
+  rotate (&encompass_, -alpha_);
+  if (dir_ == DOWN)
+    {
+      scale (&encompass_, 1, -1);
+    }
+
+  while (encompass_.size () > 1 && encompass_[1][X_AXIS] <= 0.0)
+    {
+      programming_error ("Degenerate bow: infinite steepness reqd");
+      encompass_.del (1);
+    }
+
+  Real l = encompass_.top ()[X_AXIS];
+  while (encompass_.size () > 1 && encompass_.top (1)[X_AXIS] >= l)
+    {
+      programming_error ("Degenerate bow: infinite steepness reqd");
+      encompass_.del (encompass_.size ()-2);
+    }
+}
+
+
+
 void
 Slur_bezier_bow::blow_fit ()
 {
@@ -28,7 +82,7 @@ Slur_bezier_bow::blow_fit ()
 
 
 Real
-Slur_bezier_bow::enclosed_area_f () const
+Slur_bezier_bow::get_enclosed_area () const
 {
   Real a = 0;
   for (int i=0; i < encompass_.size (); i++)
@@ -48,17 +102,17 @@ Slur_bezier_bow::enclosed_area_f () const
          x = Interval ((encompass_[i-1][X_AXIS] + encompass_[i][X_AXIS])/2, 
                        encompass_[i][X_AXIS]);
          y = Interval (0,
                      (curve_.get_other_coordinate (X_AXIS,
                                                    (x[MIN] + x[MAX]) / 2)));
+ (curve_.get_other_coordinate (X_AXIS,
+ (x[MIN] + x[MAX]) / 2)));
        }
       else
        {
          x = Interval ((encompass_[i-1][X_AXIS] + encompass_[i][X_AXIS]) / 2, 
                      (encompass_[i][X_AXIS] + encompass_[i+1][X_AXIS]) / 2);
+ (encompass_[i][X_AXIS] + encompass_[i+1][X_AXIS]) / 2);
          y = Interval (encompass_[i][Y_AXIS],
                      (curve_.get_other_coordinate (X_AXIS, x[MIN])
+ (curve_.get_other_coordinate (X_AXIS, x[MIN])
                         + curve_.get_other_coordinate (X_AXIS,
                                                      (x[MIN] + x[MAX]) / 2)
+ (x[MIN] + x[MAX]) / 2)
                         + curve_.get_other_coordinate (X_AXIS, x[MAX])) / 3);
        }
       
@@ -69,7 +123,7 @@ Slur_bezier_bow::enclosed_area_f () const
 }
 
 Array<Real>
-Slur_bezier_bow::area_x_gradients_array (Real area)
+Slur_bezier_bow::area_x_gradientses (Real area)
 {
   Real len = curve_.control_[3][X_AXIS]; 
   Real grow = len / 10.0;
@@ -78,44 +132,40 @@ Slur_bezier_bow::area_x_gradients_array (Real area)
     {
       Real r = curve_.control_[i+1][X_AXIS];
       curve_.control_[i+1][X_AXIS] += grow;
-      da[i] = (enclosed_area_f () - area) / grow;
+      da[i] = (get_enclosed_area () - area) / grow;
       curve_.control_[i+1][X_AXIS] = r; 
     }
   return da;
 }
 
+/*
+  ugh, should have another look, and use a regular optimization
+  algorithm, instead of this homebrew.
+*/
 void
-Slur_bezier_bow::minimise_enclosed_area (Paper_def* paper_l,
-                                        Real default_height)
+Slur_bezier_bow::minimise_enclosed_area (Real beauty,
+                                        SCM bezier_props)
 {
   Real length = curve_.control_[3][X_AXIS]; 
-  Real sb = paper_l->get_var ("slur_beautiful");
-  Real beautiful = length * default_height * sb;
+  Real beautiful = beauty * length * slur_height (length, h_inf_, r_0_);
 
-  DEBUG_OUT << to_str ("Beautiful: %f\n", beautiful);
-  DEBUG_OUT << to_str ("Length: %f\n", length);
-  DEBUG_OUT << to_str ("D-height: %f\n", default_height);
-  DEBUG_OUT << to_str ("FitFac: %f\n", fit_factor ());
 
   if (fit_factor () > 1.0)
     blow_fit ();
   
-  Real pct_c0 = paper_l->get_var ("bezier_pct_c0");
-  Real pct_c3 = paper_l->get_var ("bezier_pct_c3");
-  Real pct_in_max = paper_l->get_var ("bezier_pct_in_max");
-  Real pct_out_max = paper_l->get_var ("bezier_pct_out_max");
-  Real steps = paper_l->get_var ("bezier_area_steps");
+  Real pct_c0 = gh_scm2double (ly_cdr (scm_assoc (ly_symbol2scm ("bezier-pct-c0"), bezier_props)));
+  Real pct_c3 = gh_scm2double (ly_cdr (scm_assoc (ly_symbol2scm ("bezier-pct-c3"), bezier_props)));
+  Real pct_in_max =  gh_scm2double (ly_cdr (scm_assoc (ly_symbol2scm ("bezier-pct-in-max"), bezier_props)));
+  Real pct_out_max = gh_scm2double (ly_cdr (scm_assoc (ly_symbol2scm ("bezier-pct-out-max"), bezier_props)));
+  Real steps =  gh_scm2double (ly_cdr (scm_assoc (ly_symbol2scm ("bezier-area-steps"),bezier_props)));
 
   for (int i=0; i < steps; i++)
     {
-      Real area = enclosed_area_f ();
-      if (!i)
-       DEBUG_OUT << to_str ("Init area: %f\n", area);
-
+      Real area = get_enclosed_area ();
       if (area <= beautiful)
        break;
 
-      Array<Real> da = area_x_gradients_array (area);
+      Array<Real> da = area_x_gradientses (area);
 
       // urg
       Real pct = pct_c0 + pct_c3 * length * length * length;
@@ -129,26 +179,15 @@ Slur_bezier_bow::minimise_enclosed_area (Paper_def* paper_l,
                <? abs ((curve_.control_[3][X_AXIS]
                         - curve_.control_[2][X_AXIS]) / da[1]));
 
-      DEBUG_OUT << to_str ("pct: %f\n", pct);
-      DEBUG_OUT << to_str ("u: %f\n", u);
-
-      DEBUG_OUT << to_str ("da: (%f, %f)\n", da[0], da[1]);
-      DEBUG_OUT << to_str ("da*u: (%f, %f)\n", da[0]*u*pct, da[1]*u*pct);
-      DEBUG_OUT << to_str ("cx: (%f, %f)\n", curve_.control_[1][X_AXIS],
-                          curve_.control_[2][X_AXIS]);
-
       curve_.control_[1][X_AXIS] -= da[0] * u * pct;
       curve_.control_[2][X_AXIS] -= da[1] * u * pct;
     }
-
-  Real area = enclosed_area_f ();
-  DEBUG_OUT << to_str ("Exarea: %f\n", area);
 }
 
 
 
 /*
-  max ( encompass.y / curve.y )
+  max (encompass.y / curve.y)
   
  */
 Real