]> git.donarmstrong.com Git - lilypond.git/blob - flower/include/offset.hh
ba369a5c70124c7d998409ab36292aedd8d5683c
[lilypond.git] / flower / include / offset.hh
1 /*
2   This file is part of LilyPond, the GNU music typesetter.
3
4   Copyright (C) 1996--2012 Han-Wen Nienhuys
5
6   LilyPond is free software: you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation, either version 3 of the License, or
9   (at your option) any later version.
10
11   LilyPond is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   GNU General Public License for more details.
15
16   You should have received a copy of the GNU General Public License
17   along with LilyPond.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #ifndef OFFSET_HH
21 #define OFFSET_HH
22
23 #include "axis.hh"
24 #include "std-string.hh"
25 #include "real.hh"
26
27 /*
28   This is a mixture a 2D vector. Sometimes it can
29   also be convenient to think of 2D vectors as complex numbers
30   (ie. x + i y). The naming of some methods reflects that.
31 */
32 class Offset
33 {
34 public:
35   Real coordinate_a_[NO_AXES];
36
37   Real &operator [] (Axis i)
38   {
39     return coordinate_a_[i];
40   }
41
42   Real operator [] (Axis i) const
43   {
44     return coordinate_a_[i];
45   }
46
47   Offset &operator += (Offset o)
48   {
49     (*this)[X_AXIS] += o[X_AXIS];
50     (*this)[Y_AXIS] += o[Y_AXIS];
51     return *this;
52   }
53
54   Offset operator - () const
55   {
56     Offset o = *this;
57
58     o[X_AXIS] = -o[X_AXIS];
59     o[Y_AXIS] = -o[Y_AXIS];
60     return o;
61   }
62
63   Offset &operator -= (Offset o)
64   {
65     (*this)[X_AXIS] -= o[X_AXIS];
66     (*this)[Y_AXIS] -= o[Y_AXIS];
67
68     return *this;
69   }
70
71   Offset &scale (Offset o)
72   {
73     (*this)[X_AXIS] *= o[X_AXIS];
74     (*this)[Y_AXIS] *= o[Y_AXIS];
75
76     return *this;
77   }
78
79   Offset &operator /= (Real a)
80   {
81     (*this) *= 1 / a;
82     return *this;
83   }
84
85   Offset &operator *= (Real a)
86   {
87     (*this)[X_AXIS] *= a;
88     (*this)[Y_AXIS] *= a;
89
90     return *this;
91   }
92
93   Offset (Real ix, Real iy)
94   {
95     coordinate_a_[X_AXIS] = ix;
96     coordinate_a_[Y_AXIS] = iy;
97   }
98
99   Offset ()
100   {
101     coordinate_a_[X_AXIS] = coordinate_a_[Y_AXIS] = 0.0;
102   }
103
104   string to_string () const;
105
106   Offset &mirror (Axis a)
107   {
108     coordinate_a_[a] = -coordinate_a_[a];
109     return *this;
110   }
111   Offset direction () const;
112   Offset swapped () const;
113
114   Real arg () const;
115   Real angle_degrees () const;
116   Real length () const;
117   bool is_sane () const;
118   Offset operator *= (Offset z2);
119 };
120
121 #include "arithmetic-operator.hh"
122 IMPLEMENT_ARITHMETIC_OPERATOR (Offset, +);
123 IMPLEMENT_ARITHMETIC_OPERATOR (Offset, -);
124 IMPLEMENT_ARITHMETIC_OPERATOR (Offset, *);
125
126 Offset complex_multiply (Offset, Offset);
127 Offset complex_divide (Offset, Offset);
128 Offset complex_exp (Offset);
129
130 inline Offset
131 Offset::operator *= (Offset z2)
132 {
133   *this = complex_multiply (*this, z2);
134   return *this;
135 }
136
137 inline Offset
138 operator * (Real o1, Offset o2)
139 {
140   o2 *= o1;
141   return o2;
142 }
143
144 inline Offset
145 operator / (Offset o1, Real a)
146 {
147   o1 /= a;
148   return o1;
149 }
150
151 inline Offset
152 operator * (Offset o1, Real o2)
153 {
154   o1 *= o2;
155   return o1;
156 }
157
158 inline Offset
159 mirror (Offset o, Axis a)
160 {
161   o.mirror (a);
162   return o;
163 }
164
165 inline
166 Real
167 dot_product (Offset o1, Offset o2)
168 {
169   return o1[X_AXIS] * o2[X_AXIS] + o1[Y_AXIS] * o2[Y_AXIS];
170 }
171
172 #endif /* OFFSET_HH */
173