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