Mercurial > hg > svcore
comparison base/RangeMapper.h @ 912:2175c2ebd5c6 tonioni
Merge from default branch
author | Chris Cannam |
---|---|
date | Wed, 14 May 2014 09:58:07 +0100 |
parents | 12a6140b3ae0 |
children | cc27f35aa75c |
comparison
equal
deleted
inserted
replaced
901:68e880e0b857 | 912:2175c2ebd5c6 |
---|---|
17 #define _RANGE_MAPPER_H_ | 17 #define _RANGE_MAPPER_H_ |
18 | 18 |
19 #include <QString> | 19 #include <QString> |
20 | 20 |
21 #include "Debug.h" | 21 #include "Debug.h" |
22 | 22 #include <map> |
23 | 23 |
24 class RangeMapper | 24 class RangeMapper |
25 { | 25 { |
26 public: | 26 public: |
27 virtual ~RangeMapper() { } | 27 virtual ~RangeMapper() { } |
28 | |
29 /** | |
30 * Return the position that maps to the given value, rounding to | |
31 * the nearest position and clamping to the minimum and maximum | |
32 * extents of the mapper's positional range. | |
33 */ | |
28 virtual int getPositionForValue(float value) const = 0; | 34 virtual int getPositionForValue(float value) const = 0; |
35 | |
36 /** | |
37 * Return the position that maps to the given value, rounding to | |
38 * the nearest position, without clamping. That is, whatever | |
39 * mapping function is in use will be projected even outside the | |
40 * minimum and maximum extents of the mapper's positional | |
41 * range. (The mapping outside that range is not guaranteed to be | |
42 * exact, except if the mapper is a linear one.) | |
43 */ | |
44 virtual int getPositionForValueUnclamped(float value) const = 0; | |
45 | |
46 /** | |
47 * Return the value mapped from the given position, clamping to | |
48 * the minimum and maximum extents of the mapper's value range. | |
49 */ | |
29 virtual float getValueForPosition(int position) const = 0; | 50 virtual float getValueForPosition(int position) const = 0; |
51 | |
52 /** | |
53 * Return the value mapped from the given positionq, without | |
54 * clamping. That is, whatever mapping function is in use will be | |
55 * projected even outside the minimum and maximum extents of the | |
56 * mapper's value range. (The mapping outside that range is not | |
57 * guaranteed to be exact, except if the mapper is a linear one.) | |
58 */ | |
59 virtual float getValueForPositionUnclamped(int position) const = 0; | |
60 | |
61 /** | |
62 * Get the unit of the mapper's value range. | |
63 */ | |
30 virtual QString getUnit() const { return ""; } | 64 virtual QString getUnit() const { return ""; } |
31 }; | 65 }; |
32 | 66 |
33 | 67 |
34 class LinearRangeMapper : public RangeMapper | 68 class LinearRangeMapper : public RangeMapper |
35 { | 69 { |
36 public: | 70 public: |
71 /** | |
72 * Map values in range minval->maxval linearly into integer range | |
73 * minpos->maxpos. minval and minpos must be less than maxval and | |
74 * maxpos respectively. If inverted is true, the range will be | |
75 * mapped "backwards" (minval to maxpos and maxval to minpos). | |
76 */ | |
37 LinearRangeMapper(int minpos, int maxpos, | 77 LinearRangeMapper(int minpos, int maxpos, |
38 float minval, float maxval, | 78 float minval, float maxval, |
39 QString unit = "", bool inverted = false); | 79 QString unit = "", bool inverted = false); |
40 | 80 |
41 virtual int getPositionForValue(float value) const; | 81 virtual int getPositionForValue(float value) const; |
42 virtual float getValueForPosition(int position) const; | 82 virtual int getPositionForValueUnclamped(float value) const; |
83 | |
84 virtual float getValueForPosition(int position) const; | |
85 virtual float getValueForPositionUnclamped(int position) const; | |
43 | 86 |
44 virtual QString getUnit() const { return m_unit; } | 87 virtual QString getUnit() const { return m_unit; } |
45 | 88 |
46 protected: | 89 protected: |
47 int m_minpos; | 90 int m_minpos; |
50 float m_maxval; | 93 float m_maxval; |
51 QString m_unit; | 94 QString m_unit; |
52 bool m_inverted; | 95 bool m_inverted; |
53 }; | 96 }; |
54 | 97 |
55 | |
56 class LogRangeMapper : public RangeMapper | 98 class LogRangeMapper : public RangeMapper |
57 { | 99 { |
58 public: | 100 public: |
101 /** | |
102 * Map values in range minval->maxval into integer range | |
103 * minpos->maxpos such that logs of the values are mapped | |
104 * linearly. minval must be greater than zero, and minval and | |
105 * minpos must be less than maxval and maxpos respectively. If | |
106 * inverted is true, the range will be mapped "backwards" (minval | |
107 * to maxpos and maxval to minpos). | |
108 */ | |
59 LogRangeMapper(int minpos, int maxpos, | 109 LogRangeMapper(int minpos, int maxpos, |
60 float minval, float maxval, | 110 float minval, float maxval, |
61 QString m_unit = "", bool inverted = false); | 111 QString m_unit = "", bool inverted = false); |
62 | 112 |
63 static void convertRatioMinLog(float ratio, float minlog, | 113 static void convertRatioMinLog(float ratio, float minlog, |
67 static void convertMinMax(int minpos, int maxpos, | 117 static void convertMinMax(int minpos, int maxpos, |
68 float minval, float maxval, | 118 float minval, float maxval, |
69 float &ratio, float &minlog); | 119 float &ratio, float &minlog); |
70 | 120 |
71 virtual int getPositionForValue(float value) const; | 121 virtual int getPositionForValue(float value) const; |
72 virtual float getValueForPosition(int position) const; | 122 virtual int getPositionForValueUnclamped(float value) const; |
123 | |
124 virtual float getValueForPosition(int position) const; | |
125 virtual float getValueForPositionUnclamped(int position) const; | |
73 | 126 |
74 virtual QString getUnit() const { return m_unit; } | 127 virtual QString getUnit() const { return m_unit; } |
75 | 128 |
76 protected: | 129 protected: |
77 int m_minpos; | 130 int m_minpos; |
81 float m_maxlog; | 134 float m_maxlog; |
82 QString m_unit; | 135 QString m_unit; |
83 bool m_inverted; | 136 bool m_inverted; |
84 }; | 137 }; |
85 | 138 |
139 class InterpolatingRangeMapper : public RangeMapper | |
140 { | |
141 public: | |
142 typedef std::map<float, int> CoordMap; | |
143 | |
144 /** | |
145 * Given a series of (value, position) coordinate mappings, | |
146 * construct a range mapper that maps arbitrary values, in the | |
147 * range between minimum and maximum of the provided values, onto | |
148 * coordinates using linear interpolation between the supplied | |
149 * points. | |
150 * | |
151 *!!! todo: Cubic -- more generally useful than linear interpolation | |
152 *!!! todo: inverted flag | |
153 * | |
154 * The set of provided mappings must contain at least two | |
155 * coordinates. | |
156 * | |
157 * It is expected that the values and positions in the coordinate | |
158 * mappings will both be monotonically increasing (i.e. no | |
159 * inflections in the mapping curve). Behaviour is undefined if | |
160 * this is not the case. | |
161 */ | |
162 InterpolatingRangeMapper(CoordMap pointMappings, | |
163 QString unit); | |
164 | |
165 virtual int getPositionForValue(float value) const; | |
166 virtual int getPositionForValueUnclamped(float value) const; | |
167 | |
168 virtual float getValueForPosition(int position) const; | |
169 virtual float getValueForPositionUnclamped(int position) const; | |
170 | |
171 virtual QString getUnit() const { return m_unit; } | |
172 | |
173 protected: | |
174 CoordMap m_mappings; | |
175 std::map<int, float> m_reverse; | |
176 QString m_unit; | |
177 | |
178 template <typename T> | |
179 float interpolate(T *mapping, float v) const; | |
180 }; | |
181 | |
182 class AutoRangeMapper : public RangeMapper | |
183 { | |
184 public: | |
185 enum MappingType { | |
186 Interpolating, | |
187 StraightLine, | |
188 Logarithmic, | |
189 }; | |
190 | |
191 typedef std::map<float, int> CoordMap; | |
192 | |
193 /** | |
194 * Given a series of (value, position) coordinate mappings, | |
195 * construct a range mapper that maps arbitrary values, in the | |
196 * range between minimum and maximum of the provided values, onto | |
197 * coordinates. | |
198 * | |
199 * The mapping used may be | |
200 * | |
201 * Interpolating -- an InterpolatingRangeMapper will be used | |
202 * | |
203 * StraightLine -- a LinearRangeMapper from the minimum to | |
204 * maximum value coordinates will be used, ignoring all other | |
205 * supplied coordinate mappings | |
206 * | |
207 * Logarithmic -- a LogRangeMapper from the minimum to | |
208 * maximum value coordinates will be used, ignoring all other | |
209 * supplied coordinate mappings | |
210 * | |
211 * The mapping will be chosen automatically by looking at the | |
212 * supplied coordinates. If the supplied coordinates fall on a | |
213 * straight line, a StraightLine mapping will be used; if they | |
214 * fall on a log curve, a Logarithmic mapping will be used; | |
215 * otherwise an Interpolating mapping will be used. | |
216 * | |
217 *!!! todo: inverted flag | |
218 * | |
219 * The set of provided mappings must contain at least two | |
220 * coordinates, or at least three if the points are not supposed | |
221 * to be in a straight line. | |
222 * | |
223 * It is expected that the values and positions in the coordinate | |
224 * mappings will both be monotonically increasing (i.e. no | |
225 * inflections in the mapping curve). Behaviour is undefined if | |
226 * this is not the case. | |
227 */ | |
228 AutoRangeMapper(CoordMap pointMappings, | |
229 QString unit); | |
230 | |
231 ~AutoRangeMapper(); | |
232 | |
233 /** | |
234 * Return the mapping type in use. | |
235 */ | |
236 MappingType getType() const { return m_type; } | |
237 | |
238 virtual int getPositionForValue(float value) const; | |
239 virtual int getPositionForValueUnclamped(float value) const; | |
240 | |
241 virtual float getValueForPosition(int position) const; | |
242 virtual float getValueForPositionUnclamped(int position) const; | |
243 | |
244 virtual QString getUnit() const { return m_unit; } | |
245 | |
246 protected: | |
247 MappingType m_type; | |
248 CoordMap m_mappings; | |
249 QString m_unit; | |
250 RangeMapper *m_mapper; | |
251 | |
252 MappingType chooseMappingTypeFor(const CoordMap &); | |
253 }; | |
86 | 254 |
87 #endif | 255 #endif |