]> git.donarmstrong.com Git - lilypond.git/blob - lily/simple-spacer.cc
release: 1.1.4
[lilypond.git] / lily / simple-spacer.cc
1 #include "simple-spacer.hh"
2 #include "idealspacing.hh"
3 // #include ""
4
5
6 void
7 Spring_info::set(Idealspacing *i)
8 {
9   space_f_ = i->space_f_;
10   hooke_f_ = i->hooke_f_;
11 }
12
13 Spring_info::Spring_info()
14 {
15   space_f_ = 0.0;
16   hooke_f_ = 1.0;
17   blocking_stretch_f_ = infinity_f;
18   blocking_rod_l_ = 0;
19 }
20
21   
22
23 void
24 Simple_spring_spacer::init ()
25 {
26   for (PCursor<Rod_info*> i(rods_.top()); i.ok (); i++)
27     {
28       Real hooke=0.0;
29       Real dist= i->distance_f_;
30
31       hooke =0.0;
32       
33       for (int j = i->cols_[LEFT]; j < i->cols_[RIGHT]; j++)
34         {
35           hooke += 1/springs_[j].hooke_f_;
36           dist -= springs_[j].space_f_;
37         }
38       
39       hooke = 1/hooke;
40
41       for (int j = i->cols_[LEFT]; j < i->cols_[RIGHT]; j++)
42         {
43           Real block_stretch = hooke * dist / (springs_[j].space_f_ *
44                                                springs_[j].hooke_f_ );
45
46           if (block_stretch < springs_[j].blocking_stretch_f_)
47             {
48               springs_[j].blocking_stretch_f_ = block_stretch;
49               springs_[j].blocking_rod_l_ = i.ptr ();
50             }
51         }
52     }
53 }
54
55 Array<Real>
56 Simple_spring_spacer::solve ()
57 {
58   Real start_force = 0.0;
59
60   for (int i=0; i< springs_.size (); i++)
61     {
62       start_force = start_force >?
63         springs_[i].blocking_stretch_f_ * springs_[i].hooke_f_;
64     }
65
66   Array<Real> stretch_factors;
67   Array<bool> blocked;
68   int blocked_count=0; 
69   Real current_len =0.0;
70   for (int i=0; i < springs_.size (); i++)
71     {
72       Real stretch = start_force / (springs_[i].hooke_f_ * springs_[i].space_f_);
73       stretch_factors.push (stretch);
74       current_len += (1  + stretch) * springs_[i].space_f_;
75       blocked.push(false);
76     }
77
78  
79   while (blocked_count < blocked.size ())
80     {
81       Real      next_stretch = -1.0;
82       int block_index;
83       for (int i=0; i< stretch_factors.size (); i++)
84         {
85           if (!blocked[i])
86             {
87               next_stretch = next_stretch >? springs_[i].blocking_stretch_f_;
88
89               if (next_stretch < springs_[i].blocking_stretch_f_)
90                 {
91                   next_stretch = springs_[i].blocking_stretch_f_;
92                   block_index = i;
93                 }
94             }
95         }
96       current_len = 0.0;
97
98       Real force = next_stretch * (springs_[block_index].space_f_* springs_[block_index].hooke_f_);
99       for (int i=0; i< stretch_factors.size (); i++)
100         {
101           if (!blocked[i])
102             {
103               stretch_factors[i] = force / (springs_[i].space_f_ * springs_[i].hooke_f_);
104             }
105           current_len += (1.0 + stretch_factors[i]) * springs_[i].space_f_;
106         }
107
108       Rod_info *blockrod = springs_[block_index].blocking_rod_l_;
109       for (int j = blockrod->cols_ [LEFT]; j < blockrod->cols_ [RIGHT]; j++)
110         {
111           blocked[j] = true;
112           blocked_count ++;
113         }
114     }
115
116
117   Array<Real> distances;
118   for (int i=0; i < stretch_factors.size (); i++)
119     {
120       distances.push (stretch_factors[i] * springs_[i].space_f_);
121     }
122   return distances;
123 }
124