Mercurial > hg > svcore
comparison base/RangeMapper.h @ 880:b4787b595db3
Implement and test the interpolating and auto range mappers
author | Chris Cannam |
---|---|
date | Fri, 31 Jan 2014 17:09:02 +0000 |
parents | eb6b6a88faed |
children | 12a6140b3ae0 |
comparison
equal
deleted
inserted
replaced
879:eb6b6a88faed | 880:b4787b595db3 |
---|---|
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() { } |
56 float m_maxval; | 56 float m_maxval; |
57 QString m_unit; | 57 QString m_unit; |
58 bool m_inverted; | 58 bool m_inverted; |
59 }; | 59 }; |
60 | 60 |
61 | |
62 class LogRangeMapper : public RangeMapper | 61 class LogRangeMapper : public RangeMapper |
63 { | 62 { |
64 public: | 63 public: |
64 /** | |
65 * Map values in range minval->maxval into integer range | |
66 * minpos->maxpos such that logs of the values are mapped | |
67 * linearly. minval and minpos must be less than maxval and maxpos | |
68 * respectively. If inverted is true, the range will be mapped | |
69 * "backwards" (minval to maxpos and maxval to minpos). | |
70 */ | |
65 LogRangeMapper(int minpos, int maxpos, | 71 LogRangeMapper(int minpos, int maxpos, |
66 float minval, float maxval, | 72 float minval, float maxval, |
67 QString m_unit = "", bool inverted = false); | 73 QString m_unit = "", bool inverted = false); |
68 | 74 |
69 static void convertRatioMinLog(float ratio, float minlog, | 75 static void convertRatioMinLog(float ratio, float minlog, |
87 float m_maxlog; | 93 float m_maxlog; |
88 QString m_unit; | 94 QString m_unit; |
89 bool m_inverted; | 95 bool m_inverted; |
90 }; | 96 }; |
91 | 97 |
98 class InterpolatingRangeMapper : public RangeMapper | |
99 { | |
100 public: | |
101 typedef std::map<float, int> CoordMap; | |
102 | |
103 /** | |
104 * Given a series of (value, position) coordinate mappings, | |
105 * construct a range mapper that maps arbitrary values, in the | |
106 * range between minimum and maximum of the provided values, onto | |
107 * coordinates using linear interpolation between the supplied | |
108 * points. | |
109 * | |
110 *!!! todo: Cubic -- more generally useful than linear interpolation | |
111 *!!! todo: inverted flag | |
112 * | |
113 * The set of provided mappings must contain at least two | |
114 * coordinates. | |
115 * | |
116 * It is expected that the values and positions in the coordinate | |
117 * mappings will both be monotonically increasing (i.e. no | |
118 * inflections in the mapping curve). Behaviour is undefined if | |
119 * this is not the case. | |
120 */ | |
121 InterpolatingRangeMapper(CoordMap pointMappings, | |
122 QString unit); | |
123 | |
124 virtual int getPositionForValue(float value) const; | |
125 virtual float getValueForPosition(int position) const; | |
126 | |
127 virtual QString getUnit() const { return m_unit; } | |
128 | |
129 protected: | |
130 CoordMap m_mappings; | |
131 std::map<int, float> m_reverse; | |
132 QString m_unit; | |
133 }; | |
134 | |
135 class AutoRangeMapper : public RangeMapper | |
136 { | |
137 public: | |
138 enum MappingType { | |
139 Interpolating, | |
140 StraightLine, | |
141 Logarithmic, | |
142 }; | |
143 | |
144 typedef std::map<float, int> CoordMap; | |
145 | |
146 /** | |
147 * Given a series of (value, position) coordinate mappings, | |
148 * construct a range mapper that maps arbitrary values, in the | |
149 * range between minimum and maximum of the provided values, onto | |
150 * coordinates. | |
151 * | |
152 * The mapping used may be | |
153 * | |
154 * Interpolating -- an InterpolatingRangeMapper will be used | |
155 * | |
156 * StraightLine -- a LinearRangeMapper from the minimum to | |
157 * maximum value coordinates will be used, ignoring all other | |
158 * supplied coordinate mappings | |
159 * | |
160 * Logarithmic -- a LogRangeMapper from the minimum to | |
161 * maximum value coordinates will be used, ignoring all other | |
162 * supplied coordinate mappings | |
163 * | |
164 * The mapping will be chosen automatically by looking at the | |
165 * supplied coordinates. If the supplied coordinates fall on a | |
166 * straight line, a StraightLine mapping will be used; if they | |
167 * fall on a log curve, a Logarithmic mapping will be used; | |
168 * otherwise an Interpolating mapping will be used. | |
169 * | |
170 *!!! todo: inverted flag | |
171 * | |
172 * The set of provided mappings must contain at least two | |
173 * coordinates, or at least three if the points are not supposed | |
174 * to be in a straight line. | |
175 * | |
176 * It is expected that the values and positions in the coordinate | |
177 * mappings will both be monotonically increasing (i.e. no | |
178 * inflections in the mapping curve). Behaviour is undefined if | |
179 * this is not the case. | |
180 */ | |
181 AutoRangeMapper(CoordMap pointMappings, | |
182 QString unit); | |
183 | |
184 ~AutoRangeMapper(); | |
185 | |
186 /** | |
187 * Return the mapping type in use. | |
188 */ | |
189 MappingType getType() const { return m_type; } | |
190 | |
191 virtual int getPositionForValue(float value) const; | |
192 virtual float getValueForPosition(int position) const; | |
193 | |
194 virtual QString getUnit() const { return m_unit; } | |
195 | |
196 protected: | |
197 MappingType m_type; | |
198 CoordMap m_mappings; | |
199 QString m_unit; | |
200 RangeMapper *m_mapper; | |
201 | |
202 MappingType chooseMappingTypeFor(const CoordMap &); | |
203 }; | |
92 | 204 |
93 #endif | 205 #endif |