summaryrefslogtreecommitdiff
path: root/linespace.hh
blob: b9d850c602ceef687b3429ecd5204044fef39d6f (about) (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#ifndef PROBLEM_HH
#define PROBLEM_HH

#include "glob.hh"
#include "plist.hh"
#include "vray.hh"
#include "pcol.hh"
#include "matrix.hh"

/// helper struct for #Spacing_problem#
struct Colinfo {
    const PCol *col;
    bool fixed;
    Real fixpos;
    Colinfo();
    void print() const;
    Real minright()const { return col->width().max; }
    Real minleft()const { return -col->width().min; }
};


/// spacing for one line.
class Spacing_problem {
    svec<const Idealspacing*> ideals;
    svec<Colinfo> cols;

    /// the index of #c# in #cols#
    int col_id(const PCol *c) const;

    /// generate an (nonoptimal) solution
    Vector find_initial_solution() const;

    /// check if problem is too tight
    bool check_feasible() const;
    /// does #this# contain the column #w#? 
    bool contains(const PCol *w);

    /// make the energy function
    void make_matrices(Matrix &quad, Vector &lin,Real&) const;

    /// generate the LP constraints
    void make_constraints(Mixed_qp& lp) const;

public:
    /// solve the spacing problem
    svec<Real> solve() const;
    /**
    return the column positions, and the energy (last element)
    */
    /// add a idealspacing to the problem.
    void add_ideal(const Idealspacing *i);
    
    /**
    One pair of columns can have no, one or more idealspacings,
    since they can be "summed" if the columns to which #i# refers are
    not in this problem, the spacing is ignored.
    */
    
    
    /// add a col to the problem
    void add_column(const PCol *, bool fixed=false, Real fixpos=0.0);
    /** columns have to be added left to right. The column contains
      info on it's minimum width.
    */


    bool check_constraints(Vector v) const;

    Vector try_initial_solution() const;
    void OK() const;
    void print() const;
    void print_ideal(const Idealspacing*)const;
};


/** the problem, given by the columns (which include constraints) and
    intercolumn spacing. The problem is:

    Generate a spacing which
    \begin{itemize}
    \item
    Satisfies spacing constraints (notes can't be printed through each other)
    \item
    Looks good, ie tries to conform to  an ideal spacing as much as possible.
    \end{itemize}
    This is converted by regarding idealspacing as "springs" attached
    to columns. The equilibrium of one spring is the ideal
    distance. The columns have a size, this imposes "hard" constraints
    on the distances. This transforms the problem into a quadratic
    programming problem with linear constraints.

    The quality is given by the total potential energy in the
    springs. The lower the energy, the better the configuration.
*/
#endif