]> git.donarmstrong.com Git - lilypond.git/blob - lily/include/linespace.hh
release: 0.0.57
[lilypond.git] / lily / include / linespace.hh
1 #ifndef PROBLEM_HH
2 #define PROBLEM_HH
3
4 #include "glob.hh"
5 #include "plist.hh"
6 #include "varray.hh"
7 #include "vector.hh"
8 #include "interval.hh"
9
10 /// helper struct for #Spacing_problem#
11 struct Colinfo {
12     PCol const *pcol_;
13     Real const * fixpos;
14     Interval width;
15     
16     /* *************** */
17     Colinfo();
18     void operator=(Colinfo const&);
19     Colinfo(Colinfo const&);
20     ~Colinfo();
21     Colinfo(PCol const *,Real const *);
22     void print() const;
23     bool fixed() const { return fixpos;}
24     Real fixed_position()const { return *fixpos; }
25     Real minright() const { return width.right; }
26     Real minleft() const { return -width.left; }
27 };
28
29
30 /** the problem, given by the columns (which include constraints) and
31     intercolumn spacing. The problem is:
32
33     Generate a spacing which
34     \begin{itemize}
35     \item
36     Satisfies spacing constraints (notes can't be printed through each other)
37     \item
38     Looks good, ie tries to conform to  an ideal spacing as much as possible.
39     \end{itemize}
40     This is converted by regarding idealspacing as "springs" attached
41     to columns. The equilibrium of one spring is the ideal
42     distance. The columns have a size, this imposes "hard" constraints
43     on the distances. This transforms the problem into a quadratic
44     programming problem with linear constraints.
45
46     The quality is given by the total potential energy in the
47     springs. The lower the energy, the better the configuration.
48
49     TODO: make item widths work per pstaff.
50
51 */
52 class Spacing_problem {
53     Array<Idealspacing const *> ideals;
54     Array<Colinfo> cols;
55
56     /// the index of #c# in #cols#
57     int col_id(PCol const *c) const;
58
59     /// generate an (nonoptimal) solution
60     Vector find_initial_solution() const;
61
62     /// check if problem is too tight
63     bool check_feasible() const;
64
65     /// does #this# contain the column #w#? 
66     bool contains(PCol const *w);
67
68     /// make the energy function
69     void make_matrices(Matrix &quad, Vector &lin,Real&) const;
70
71     /// generate the LP constraints
72     void make_constraints(Mixed_qp& lp) const;
73
74 public:
75     /** solve the spacing problem
76       
77       @return the column positions, and the energy (last element)
78
79       */
80     Array<Real> solve() const;
81
82     
83     /**
84        add a idealspacing to the problem.
85       
86     One pair of columns can have no, one or more idealspacings,
87     since they can be "summed" if the columns to which #i# refers are
88     not in this problem, the spacing is ignored.
89     */
90     void add_ideal(Idealspacing const *i);
91     
92     
93     /** add a col to the problem. columns have to be added left to right. The column contains
94       info on it's minimum width.
95     */
96     void add_column(PCol const *, bool fixed=false, Real fixpos=0.0);
97  
98
99
100     bool check_constraints(Vector v) const;
101
102     Vector try_initial_solution() const;
103     void OK() const;
104     void print() const;
105     void print_ideal(Idealspacing const *)const;
106 };
107
108
109 #endif