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