1 #include "viewmapper.h"
2 
ZeViewMapper(QObject * parent)3 ZeViewMapper::ZeViewMapper(QObject *parent) : QObject(parent)
4 {
5     targetTicksNum = TARGET_TICKS_NUM;
6 }
7 
setViewSettings(const ZeViewSettings & viewSettings)8 void ZeViewMapper::setViewSettings(const ZeViewSettings &viewSettings)
9 {
10     axesSettings = viewSettings.axes;
11     gridSettings = viewSettings.grid;
12 
13     setGraphRange(viewSettings.range);
14 }
15 
setGraphRange(const GraphRange & range)16 void ZeViewMapper::setGraphRange(const GraphRange &range)
17 {
18     setXmax(range.x.max);
19     setYmax(range.y.max);
20     setXmin(range.x.min);
21     setYmin(range.y.min);
22 }
23 
getGraphRange()24 GraphRange ZeViewMapper::getGraphRange()
25 {
26     GraphRange range;
27 
28     range.x.min = Xmin;
29     range.y.min = Ymin;
30 
31     range.x.max = Xmax;
32     range.y.max = Ymax;
33 
34     return range;
35 }
36 
ZeViewMapper(const ZeViewMapper & other,QObject * parent)37 ZeViewMapper::ZeViewMapper(const ZeViewMapper &other, QObject *parent) : QObject(parent)
38 {
39     Xmin = other.Xmin;
40     Xmax = other.Xmax;
41     Ymin = other.Ymin;
42     Ymax = other.Ymax;
43 
44     lgXmin = other.lgXmin;
45     lgXmax = other.lgXmax;
46     lgYmin = other.lgYmin;
47     lgYmax = other.lgYmax;
48 }
49 
operator =(const ZeViewMapper & other)50 ZeViewMapper& ZeViewMapper::operator=(const ZeViewMapper &other)
51 {
52     Xmin = other.Xmin;
53     Xmax = other.Xmax;
54     Ymin = other.Ymin;
55     Ymax = other.Ymax;
56 
57     lgXmin = other.lgXmin;
58     lgXmax = other.lgXmax;
59     lgYmin = other.lgYmin;
60     lgYmax = other.lgYmax;
61 
62     return *this;
63 }
64 
getRect() const65 QRectF ZeViewMapper::getRect() const
66 {
67     QRectF graphWin;
68     graphWin.setBottom(Ymin);
69     graphWin.setTop(Ymax);
70     graphWin.setLeft(Xmin);
71     graphWin.setRight(Xmax);
72     return graphWin;
73 }
74 
getLogRect() const75 QRectF ZeViewMapper::getLogRect() const
76 {
77     QRectF graphlLgWin;
78     graphlLgWin.setBottom(lgYmin);
79     graphlLgWin.setTop(lgYmax);
80     graphlLgWin.setLeft(lgXmin);
81     graphlLgWin.setRight(lgXmax);
82     return graphlLgWin;
83 }
84 
setViewRect(QRectF rect)85 void ZeViewMapper::setViewRect(QRectF rect)
86 {
87     setViewXmax(rect.right());
88     setViewXmin(rect.left());
89     setViewYmax(rect.top());
90     setViewYmin(rect.bottom());
91 
92     verifyOrthonormality();
93 }
94 
getViewRect() const95 QRectF ZeViewMapper::getViewRect() const
96 {
97     QRectF viewWin;
98 
99     if(axesSettings.x.axisType == ZeAxisType::LOG)
100     {
101         viewWin.setLeft(lgXmin);
102         viewWin.setRight(lgXmax);
103     }
104     else
105     {
106         viewWin.setLeft(Xmin);
107         viewWin.setRight(Xmax);
108     }
109 
110     if(axesSettings.y.axisType == ZeAxisType::LOG)
111     {
112         viewWin.setBottom(lgYmin);
113         viewWin.setTop(lgYmax);
114     }
115     else
116     {
117         viewWin.setBottom(Ymin);
118         viewWin.setTop(Ymax);
119     }
120 
121     return viewWin;
122 }
123 
zoomYview(double ratio)124 void ZeViewMapper::zoomYview(double ratio)
125 {
126     if(axesSettings.y.axisType == ZeAxisType::LOG)
127     {
128         double val = (lgYmax - lgYmin) * ratio;
129         setlgYmax(lgYmax + val);
130         setlgYmin(lgYmin - val);
131     }
132     else
133     {
134         double val = (Ymax - Ymin) * ratio;
135         setYmax(Ymax + val);
136         setYmin(Ymin - val);
137     }
138 
139     verifyOrthonormality();
140 }
141 
zoomXview(double ratio)142 void ZeViewMapper::zoomXview(double ratio)
143 {
144     if(axesSettings.x.axisType == ZeAxisType::LOG)
145     {
146         double val = (lgXmax - lgXmin) * ratio;
147         setlgXmax(lgXmax + val);
148         setlgXmin(lgXmin - val);
149     }
150     else
151     {
152         double val = (Xmax - Xmin) * ratio;
153         setXmax(Xmax + val);
154         setXmin(Xmin - val);
155     }
156 
157     verifyOrthonormality();
158 }
159 
zoomView(QPointF center,double ratio)160 void ZeViewMapper::zoomView(QPointF center, double ratio)
161 {
162     double Xamp = Xmax - Xmin , Yamp = Ymax - Ymin;
163     if(MAX_AMPLITUDE > Xamp && Xamp > MIN_AMPLITUDE &&
164             MAX_AMPLITUDE > Yamp && Yamp > MIN_AMPLITUDE)
165     {
166         if(axesSettings.x.axisType == ZeAxisType::LOG)
167         {
168             setlgXmax(lgXmax - (lgXmax - center.x())*ratio);
169             setlgXmin(lgXmin - (lgXmin - center.x())*ratio);
170         }
171         else
172         {
173             setXmax(Xmax - (Xmax - center.x())*ratio);
174             setXmin(Xmin - (Xmin - center.x())*ratio);
175         }
176 
177         if(axesSettings.x.axisType == ZeAxisType::LOG)
178         {
179             setlgYmax(lgYmax - (lgYmax - center.y())*ratio);
180             setlgYmin(lgYmin - (lgYmin - center.y())*ratio);
181         }
182         else
183         {
184             setYmax(Ymax - (Ymax - center.y())*ratio);
185             setYmin(Ymin - (Ymin - center.y())*ratio);
186         }
187     }
188 }
189 
getLinearAxisTicks(double windowWidth,ZeAxisRange range,ZeAxisName axisName,QFontMetrics metrics)190 ZeLinAxisTicks ZeViewMapper::getLinearAxisTicks(double windowWidth,
191                                             ZeAxisRange range,
192                                             ZeAxisName axisName,
193                                             QFontMetrics metrics)
194 {
195 
196     ZeLinAxisTicks axisTicks;
197     axisTicks.offset.sumOffset = 0;
198     axisTicks.offset.powerOffset = 0;
199 
200     ZeLinAxisSettings axisSettings = axisName == ZeAxisName::X ? axesSettings.x.linSettings : axesSettings.y.linSettings;
201 
202     const double &constantMultiplier = axisSettings.constantMultiplier;
203     double amplitude = range.amplitude();
204 
205     double amplitudeLog10 = floor(log10(amplitude));
206     double minLog10 = floor(log10(range.min / constantMultiplier));
207 
208     if(amplitudeLog10 < minLog10 - axisSettings.maxDigitsNum)
209     {
210         double digitsNum = minLog10 - axisSettings.maxDigitsNum - amplitudeLog10;
211 
212         double tenPower = pow(10, digitsNum);
213         axisTicks.offset.sumOffset = trunc(range.min * tenPower) / tenPower;
214     }
215 
216     double targetPower = floor(log10(amplitude / constantMultiplier / targetTicksNum));
217 
218     double baseStep = pow(10, targetPower);
219     double realStep = baseStep * constantMultiplier;
220 
221     ZeLinAxisTick firstTick;
222     firstTick.pos = ceil(range.min / realStep) * realStep;
223     firstTick.multiplier = firstTick.pos / axisSettings.constantMultiplier - axisTicks.offset.sumOffset;
224 
225     axisTicks.ticks << firstTick;
226 
227     ZeLinAxisTick tick;
228 
229     while(axisTicks.ticks.last().pos < range.max)
230     {
231         tick.pos = axisTicks.ticks.last().pos + realStep;
232         tick.multiplier = axisTicks.ticks.last().multiplier + baseStep;
233 
234         axisTicks.ticks << tick;
235     }
236 
237     axisTicks.ticks.removeLast();
238 
239     return axisTicks;
240 }
241 
translateView(QPointF vec)242 void ZeViewMapper::translateView(QPointF vec)
243 {
244     if(axesSettings.x.axisType == ZeAxisType::LOG)
245     {
246         setlgXmax(lgXmax + vec.x());
247         setlgXmin(lgXmin + vec.x());
248     }
249     else
250     {
251         setXmax(Xmax + vec.x());
252         setXmin(Xmin + vec.x());
253     }
254 
255     if(axesSettings.y.axisType == ZeAxisType::LOG)
256     {
257         setlgYmax(lgYmax + vec.y());
258         setlgYmin(lgYmin + vec.y());
259     }
260     else
261     {
262         setYmax(Ymax + vec.y());
263         setYmin(Ymin + vec.y());
264     }
265 }
266 
viewToUnitY(double viewY) const267 double ZeViewMapper::viewToUnitY(double viewY) const // viewY =
268 {
269     if(axesSettings.x.axisType == ZeAxisType::LOG)
270     {
271         return pow(axesSettings.y.logSettings.base, viewY);
272     }
273     else
274     {
275         return viewY;
276     }
277 }
278 
unitToViewY(double unitY) const279 double ZeViewMapper::unitToViewY(double unitY) const
280 {
281     if(axesSettings.y.axisType == ZeAxisType::LOG)
282     {
283         return log(unitY)/log(axesSettings.y.logSettings.base);
284     }
285     else
286     {
287         return unitY;
288     }
289 }
290 
getXmin()291 double ZeViewMapper::getXmin()
292 {
293     return Xmin;
294 }
295 
getXmax()296 double ZeViewMapper::getXmax()
297 {
298     return Xmax;
299 }
300 
getYmin()301 double ZeViewMapper::getYmin()
302 {
303     return Ymin;
304 }
305 
getYmax()306 double ZeViewMapper::getYmax()
307 {
308     return Ymax;
309 }
310 
viewToUnitX(double viewX) const311 double ZeViewMapper::viewToUnitX(double viewX) const
312 {
313     if(axesSettings.x.axisType == ZeAxisType::LOG)
314     {
315         return pow(axesSettings.x.logSettings.base, viewX);
316     }
317     else
318     {
319         return viewX;
320     }
321 }
322 
unitToViewX(double unitX) const323 double ZeViewMapper::unitToViewX(double unitX) const
324 {
325     if(axesSettings.x.axisType == ZeAxisType::LOG)
326     {
327         return log(unitX)/log(axesSettings.x.logSettings.base);
328     }
329     else
330     {
331         return unitX;
332     }
333 }
334 
setViewXmin(double val)335 void ZeViewMapper::setViewXmin(double val)
336 {
337     if(axesSettings.x.axisType == ZeAxisType::LOG)
338     {
339         setlgXmin(val);
340     }
341     else
342     {
343         setXmin(val);
344     }
345 
346     verifyOrthonormality();
347 }
348 
setViewXmax(double val)349 void ZeViewMapper::setViewXmax(double val)
350 {
351     if(axesSettings.x.axisType == ZeAxisType::LOG)
352     {
353         setlgXmax(val);
354     }
355     else
356     {
357         setXmax(val);
358     }
359 
360     verifyOrthonormality();
361 }
362 
setViewYmin(double val)363 void ZeViewMapper::setViewYmin(double val)
364 {
365     if(axesSettings.y.axisType == ZeAxisType::LOG)
366     {
367         setlgYmin(val);
368     }
369     else
370     {
371         setYmin(val);
372     }
373 
374     verifyOrthonormality();
375 }
376 
setViewYmax(double val)377 void ZeViewMapper::setViewYmax(double val)
378 {
379     if(axesSettings.y.axisType == ZeAxisType::LOG)
380     {
381         setlgYmax(val);
382     }
383     else
384     {
385         setYmax(val);
386     }
387 
388     verifyOrthonormality();
389 }
390 
verifyOrthonormality()391 void ZeViewMapper::verifyOrthonormality()
392 {
393     // TODO: do somethings when it's log
394     if(axesSettings.orthonormal and axesSettings.x.axisType == ZeAxisType::LINEAR
395             and axesSettings.y.axisType == ZeAxisType::LINEAR)
396     {
397         double uniteY = viewPxSize.height() / getViewRect().height();
398         double uniteX = viewPxSize.width() / getViewRect().width();
399 
400         double ratio =  uniteX / uniteY;
401         zoomYview(ratio);
402     }
403 }
404 
setlgXmin(double val)405 void ZeViewMapper::setlgXmin(double val)
406 {
407     lgXmin = val;
408     Xmin = pow(axesSettings.x.logSettings.base, lgXmin);
409 }
410 
setlgXmax(double val)411 void ZeViewMapper::setlgXmax(double val)
412 {
413     lgXmax = val;
414     Xmax = pow(axesSettings.x.logSettings.base, lgXmax);
415 }
416 
setlgYmin(double val)417 void ZeViewMapper::setlgYmin(double val)
418 {
419     lgYmin = val;
420     Ymin = pow(axesSettings.y.logSettings.base, lgYmin);
421 }
422 
setlgYmax(double val)423 void ZeViewMapper::setlgYmax(double val)
424 {
425     lgYmax = val;
426     Ymax = pow(axesSettings.y.logSettings.base, lgYmax);
427 }
428 
setXmin(double val)429 void ZeViewMapper::setXmin(double val)
430 {
431     Xmin = val;
432     lgXmin = log(Xmin)/log(axesSettings.x.logSettings.base);
433 }
434 
setXmax(double val)435 void ZeViewMapper::setXmax(double val)
436 {
437     Xmax = val;
438     lgXmax = log(Xmax)/log(axesSettings.x.logSettings.base);
439 }
440 
setYmin(double val)441 void ZeViewMapper::setYmin(double val)
442 {
443     Ymin = val;
444     lgYmin = log(Ymin)/log(axesSettings.y.logSettings.base);
445 }
446 
setYmax(double val)447 void ZeViewMapper::setYmax(double val)
448 {
449     Ymax = val;
450     lgYmax = log(Ymax)/log(axesSettings.y.logSettings.base);
451 }
452