Qwt User's Guide: qwt_scale_engine.cpp Source File

Qwt User's Guide 6.2.0

qwt_scale_engine.cpp
1 /******************************************************************************
2 * Qwt Widget Library
3 * Copyright (C) 1997 Josef Wilgen
4 * Copyright (C) 2002 Uwe Rathmann
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the Qwt License, Version 1.0
8 *****************************************************************************/
9
10 #include "qwt_scale_engine.h"
11 #include "qwt_math.h"
12 #include "qwt_interval.h"
13 #include "qwt_transform.h"
14
15 #include <qdebug.h>
16
17 #include <limits>
18
19 static inline double qwtLog( double base, double value )
20 {
21 return std::log( value ) / std::log( base );
22 }
23
24 static inline QwtInterval qwtLogInterval( double base, const QwtInterval& interval )
25 {
26 return QwtInterval( qwtLog( base, interval.minValue() ),
27 qwtLog( base, interval.maxValue() ) );
28 }
29
30 static inline QwtInterval qwtPowInterval( double base, const QwtInterval& interval )
31 {
32 return QwtInterval( std::pow( base, interval.minValue() ),
33 std::pow( base, interval.maxValue() ) );
34 }
35
36 #if 1
37
38 // this version often doesn't find the best ticks: f.e for 15: 5, 10
39 static double qwtStepSize( double intervalSize, int maxSteps, uint base )
40 {
41 const double minStep =
42 QwtScaleArithmetic::divideInterval( intervalSize, maxSteps, base );
43
44 if ( minStep != 0.0 )
45 {
46 // # ticks per interval
47 const int numTicks = qwtCeil( qAbs( intervalSize / minStep ) ) - 1;
48
49 // Do the minor steps fit into the interval?
50 if ( qwtFuzzyCompare( ( numTicks + 1 ) * qAbs( minStep ),
51 qAbs( intervalSize ), intervalSize ) > 0 )
52 {
53 // The minor steps doesn't fit into the interval
54 return 0.5 * intervalSize;
55 }
56 }
57
58 return minStep;
59 }
60
61 #else
62
63 static double qwtStepSize( double intervalSize, int maxSteps, uint base )
64 {
65 if ( maxSteps <= 0 )
66 return 0.0;
67
68 if ( maxSteps > 2 )
69 {
70 for ( int numSteps = maxSteps; numSteps > 1; numSteps-- )
71 {
72 const double stepSize = intervalSize / numSteps;
73
74 const double p = std::floor( std::log( stepSize ) / std::log( base ) );
75 const double fraction = std::pow( base, p );
76
77 for ( uint n = base; n > 1; n /= 2 )
78 {
79 if ( qFuzzyCompare( stepSize, n * fraction ) )
80 return stepSize;
81
82 if ( n == 3 && ( base % 2 ) == 0 )
83 {
84 if ( qFuzzyCompare( stepSize, 2 * fraction ) )
85 return stepSize;
86 }
87 }
88 }
89 }
90
91 return intervalSize * 0.5;
92 }
93
94 #endif
95
96 static const double _eps = 1.0e-6;
97
108 double QwtScaleArithmetic::ceilEps( double value,
109 double intervalSize )
110 {
111 const double eps = _eps * intervalSize;
112
113 value = ( value - eps ) / intervalSize;
114 return std::ceil( value ) * intervalSize;
115 }
116
126 double QwtScaleArithmetic::floorEps( double value, double intervalSize )
127 {
128 const double eps = _eps * intervalSize;
129
130 value = ( value + eps ) / intervalSize;
131 return std::floor( value ) * intervalSize;
132 }
133
143 double QwtScaleArithmetic::divideEps( double intervalSize, double numSteps )
144 {
145 if ( numSteps == 0.0 || intervalSize == 0.0 )
146 return 0.0;
147
148 return ( intervalSize - ( _eps * intervalSize ) ) / numSteps;
149 }
150
160 double QwtScaleArithmetic::divideInterval(
161 double intervalSize, int numSteps, uint base )
162 {
163 if ( numSteps <= 0 )
164 return 0.0;
165
166 const double v = QwtScaleArithmetic::divideEps( intervalSize, numSteps );
167 if ( v == 0.0 )
168 return 0.0;
169
170 const double lx = qwtLog( base, std::fabs( v ) );
171 const double p = std::floor( lx );
172
173 const double fraction = std::pow( base, lx - p );
174
175 uint n = base;
176 while ( ( n > 1 ) && ( fraction <= n / 2 ) )
177 n /= 2;
178
179 double stepSize = n * std::pow( base, p );
180 if ( v < 0 )
181 stepSize = -stepSize;
182
183 return stepSize;
184 }
185
186 class QwtScaleEngine::PrivateData
187 {
188 public:
189 PrivateData():
190 attributes( QwtScaleEngine::NoAttribute ),
191 lowerMargin( 0.0 ),
192 upperMargin( 0.0 ),
193 referenceValue( 0.0 ),
194 base( 10 ),
195 transform( NULL )
196 {
197 }
198
199 ~PrivateData()
200 {
201 delete transform;
202 }
203
204 QwtScaleEngine::Attributes attributes;
205
206 double lowerMargin;
207 double upperMargin;
208
209 double referenceValue;
210
211 uint base;
212
213 QwtTransform* transform;
214 };
215
222 QwtScaleEngine::QwtScaleEngine( uint base )
223 {
224 m_data = new PrivateData;
225 setBase( base );
226 }
227
228
230 QwtScaleEngine::~QwtScaleEngine ()
231 {
232 delete m_data;
233 }
234
248 void QwtScaleEngine::setTransformation( QwtTransform* transform )
249 {
250 if ( transform != m_data->transform )
251 {
252 delete m_data->transform;
253 m_data->transform = transform;
254 }
255 }
256
265 QwtTransform* QwtScaleEngine::transformation() const
266 {
267 QwtTransform* transform = NULL;
268 if ( m_data->transform )
269 transform = m_data->transform->copy();
270
271 return transform;
272 }
273
280 double QwtScaleEngine::lowerMargin() const
281 {
282 return m_data->lowerMargin;
283 }
284
291 double QwtScaleEngine::upperMargin() const
292 {
293 return m_data->upperMargin;
294 }
295
312 void QwtScaleEngine::setMargins( double lower, double upper )
313 {
314 m_data->lowerMargin = qwtMaxF( lower, 0.0 );
315 m_data->upperMargin = qwtMaxF( upper, 0.0 );
316 }
317
326 double QwtScaleEngine::divideInterval(
327 double intervalSize, int numSteps ) const
328 {
329 return QwtScaleArithmetic::divideInterval(
330 intervalSize, numSteps, m_data->base );
331 }
332
341 bool QwtScaleEngine::contains(
342 const QwtInterval& interval, double value ) const
343 {
344 if ( !interval.isValid() )
345 return false;
346
347 if ( qwtFuzzyCompare( value, interval.minValue(), interval.width() ) < 0 )
348 return false;
349
350 if ( qwtFuzzyCompare( value, interval.maxValue(), interval.width() ) > 0 )
351 return false;
352
353 return true;
354 }
355
364 QList< double > QwtScaleEngine::strip( const QList< double >& ticks,
365 const QwtInterval& interval ) const
366 {
367 if ( !interval.isValid() || ticks.count() == 0 )
368 return QList< double >();
369
370 if ( contains( interval, ticks.first() )
371 && contains( interval, ticks.last() ) )
372 {
373 return ticks;
374 }
375
376 QList< double > strippedTicks;
377 for ( int i = 0; i < ticks.count(); i++ )
378 {
379 if ( contains( interval, ticks[i] ) )
380 strippedTicks += ticks[i];
381 }
382 return strippedTicks;
383 }
384
395 QwtInterval QwtScaleEngine::buildInterval( double value ) const
396 {
397 const double delta = ( value == 0.0 ) ? 0.5 : qAbs( 0.5 * value );
398 const double max = std::numeric_limits< double >::max();
399
400 if ( max - delta < value )
401 return QwtInterval( max - delta, max );
402
403 if ( -max + delta > value )
404 return QwtInterval( -max, -max + delta );
405
406 return QwtInterval( value - delta, value + delta );
407 }
408
417 void QwtScaleEngine::setAttribute( Attribute attribute, bool on )
418 {
419 if ( on )
420 m_data->attributes |= attribute;
421 else
422 m_data->attributes &= ~attribute;
423 }
424
431 bool QwtScaleEngine::testAttribute( Attribute attribute ) const
432 {
433 return ( m_data->attributes & attribute );
434 }
435
442 void QwtScaleEngine::setAttributes( Attributes attributes )
443 {
444 m_data->attributes = attributes;
445 }
446
451 QwtScaleEngine::Attributes QwtScaleEngine::attributes() const
452 {
453 return m_data->attributes;
454 }
455
465 void QwtScaleEngine::setReference( double reference )
466 {
467 m_data->referenceValue = reference;
468 }
469
474 double QwtScaleEngine::reference() const
475 {
476 return m_data->referenceValue;
477 }
478
491 void QwtScaleEngine::setBase( uint base )
492 {
493 m_data->base = qMax( base, 2U );
494 }
495
500 uint QwtScaleEngine::base() const
501 {
502 return m_data->base;
503 }
504
511 QwtLinearScaleEngine::QwtLinearScaleEngine( uint base ):
512 QwtScaleEngine( base )
513 {
514 }
515
517 QwtLinearScaleEngine::~QwtLinearScaleEngine()
518 {
519 }
520
531 void QwtLinearScaleEngine::autoScale( int maxNumSteps,
532 double& x1, double& x2, double& stepSize ) const
533 {
534 QwtInterval interval( x1, x2 );
535 interval = interval.normalized();
536
537 interval.setMinValue( interval.minValue() - lowerMargin() );
538 interval.setMaxValue( interval.maxValue() + upperMargin() );
539
540 if ( testAttribute( QwtScaleEngine::Symmetric ) )
541 interval = interval.symmetrize( reference() );
542
543 if ( testAttribute( QwtScaleEngine::IncludeReference ) )
544 interval = interval.extend( reference() );
545
546 if ( interval.width() == 0.0 )
547 interval = buildInterval( interval.minValue() );
548
549 stepSize = QwtScaleArithmetic::divideInterval(
550 interval.width(), qMax( maxNumSteps, 1 ), base() );
551
552 if ( !testAttribute( QwtScaleEngine::Floating ) )
553 interval = align( interval, stepSize );
554
555 x1 = interval.minValue();
556 x2 = interval.maxValue();
557
558 if ( testAttribute( QwtScaleEngine::Inverted ) )
559 {
560 qSwap( x1, x2 );
561 stepSize = -stepSize;
562 }
563 }
564
577 QwtScaleDiv QwtLinearScaleEngine::divideScale( double x1, double x2,
578 int maxMajorSteps, int maxMinorSteps, double stepSize ) const
579 {
580 QwtInterval interval = QwtInterval( x1, x2 ).normalized();
581
582 if ( interval.widthL() > std::numeric_limits< double >::max() )
583 {
584 qWarning() << "QwtLinearScaleEngine::divideScale: overflow";
585 return QwtScaleDiv();
586 }
587
588 if ( interval.width() <= 0 )
589 return QwtScaleDiv();
590
591 stepSize = qAbs( stepSize );
592 if ( stepSize == 0.0 )
593 {
594 if ( maxMajorSteps < 1 )
595 maxMajorSteps = 1;
596
597 stepSize = QwtScaleArithmetic::divideInterval(
598 interval.width(), maxMajorSteps, base() );
599 }
600
601 QwtScaleDiv scaleDiv;
602
603 if ( stepSize != 0.0 )
604 {
605 QList< double > ticks[QwtScaleDiv::NTickTypes];
606 buildTicks( interval, stepSize, maxMinorSteps, ticks );
607
608 scaleDiv = QwtScaleDiv( interval, ticks );
609 }
610
611 if ( x1 > x2 )
612 scaleDiv.invert();
613
614 return scaleDiv;
615 }
616
627 void QwtLinearScaleEngine::buildTicks(
628 const QwtInterval& interval, double stepSize, int maxMinorSteps,
629 QList< double > ticks[QwtScaleDiv::NTickTypes] ) const
630 {
631 const QwtInterval boundingInterval = align( interval, stepSize );
632
633 ticks[QwtScaleDiv::MajorTick] =
634 buildMajorTicks( boundingInterval, stepSize );
635
636 if ( maxMinorSteps > 0 )
637 {
638 buildMinorTicks( ticks[QwtScaleDiv::MajorTick], maxMinorSteps, stepSize,
639 ticks[QwtScaleDiv::MinorTick], ticks[QwtScaleDiv::MediumTick] );
640 }
641
642 for ( int i = 0; i < QwtScaleDiv::NTickTypes; i++ )
643 {
644 ticks[i] = strip( ticks[i], interval );
645
646 // ticks very close to 0.0 are explicitly set to 0.0
647
648 for ( int j = 0; j < ticks[i].count(); j++ )
649 {
650 if ( qwtFuzzyCompare( ticks[i][j], 0.0, stepSize ) == 0 )
651 ticks[i][j] = 0.0;
652 }
653 }
654 }
655
664 QList< double > QwtLinearScaleEngine::buildMajorTicks(
665 const QwtInterval& interval, double stepSize ) const
666 {
667 int numTicks = qRound( interval.width() / stepSize ) + 1;
668 if ( numTicks > 10000 )
669 numTicks = 10000;
670
671 QList< double > ticks;
672 ticks.reserve( numTicks );
673
674 ticks += interval.minValue();
675 for ( int i = 1; i < numTicks - 1; i++ )
676 ticks += interval.minValue() + i * stepSize;
677 ticks += interval.maxValue();
678
679 return ticks;
680 }
681
692 void QwtLinearScaleEngine::buildMinorTicks(
693 const QList< double >& majorTicks,
694 int maxMinorSteps, double stepSize,
695 QList< double >& minorTicks,
696 QList< double >& mediumTicks ) const
697 {
698 double minStep = qwtStepSize( stepSize, maxMinorSteps, base() );
699 if ( minStep == 0.0 )
700 return;
701
702 // # ticks per interval
703 const int numTicks = qwtCeil( qAbs( stepSize / minStep ) ) - 1;
704
705 int medIndex = -1;
706 if ( numTicks % 2 )
707 medIndex = numTicks / 2;
708
709 // calculate minor ticks
710
711 for ( int i = 0; i < majorTicks.count(); i++ )
712 {
713 double val = majorTicks[i];
714 for ( int k = 0; k < numTicks; k++ )
715 {
716 val += minStep;
717
718 double alignedValue = val;
719 if ( qwtFuzzyCompare( val, 0.0, stepSize ) == 0 )
720 alignedValue = 0.0;
721
722 if ( k == medIndex )
723 mediumTicks += alignedValue;
724 else
725 minorTicks += alignedValue;
726 }
727 }
728 }
729
741 QwtInterval QwtLinearScaleEngine::align(
742 const QwtInterval& interval, double stepSize ) const
743 {
744 double x1 = interval.minValue();
745 double x2 = interval.maxValue();
746
747 // when there is no rounding beside some effect, when
748 // calculating with doubles, we keep the original value
749
750 const double eps = 0.000000000001; // since Qt 4.8: qFuzzyIsNull
751 const double max = std::numeric_limits< double >::max();
752
753 if ( -max + stepSize <= x1 )
754 {
755 const double x = QwtScaleArithmetic::floorEps( x1, stepSize );
756 if ( qAbs(x) <= eps || !qFuzzyCompare( x1, x ) )
757 x1 = x;
758 }
759
760 if ( max - stepSize >= x2 )
761 {
762 const double x = QwtScaleArithmetic::ceilEps( x2, stepSize );
763 if ( qAbs(x) <= eps || !qFuzzyCompare( x2, x ) )
764 x2 = x;
765 }
766
767 return QwtInterval( x1, x2 );
768 }
769
776 QwtLogScaleEngine::QwtLogScaleEngine( uint base ):
777 QwtScaleEngine( base )
778 {
779 setTransformation( new QwtLogTransform() );
780 }
781
783 QwtLogScaleEngine::~QwtLogScaleEngine()
784 {
785 }
786
797 void QwtLogScaleEngine::autoScale( int maxNumSteps,
798 double& x1, double& x2, double& stepSize ) const
799 {
800 if ( x1 > x2 )
801 qSwap( x1, x2 );
802
803 const double logBase = base();
804
805 QwtInterval interval( x1 / std::pow( logBase, lowerMargin() ),
806 x2 * std::pow( logBase, upperMargin() ) );
807
808 if ( interval.maxValue() / interval.minValue() < logBase )
809 {
810 // scale width is less than one step -> try to build a linear scale
811
812 QwtLinearScaleEngine linearScaler;
813 linearScaler.setAttributes( attributes() );
814 linearScaler.setReference( reference() );
815 linearScaler.setMargins( lowerMargin(), upperMargin() );
816
817 linearScaler.autoScale( maxNumSteps, x1, x2, stepSize );
818
819 QwtInterval linearInterval = QwtInterval( x1, x2 ).normalized();
820 linearInterval = linearInterval.limited(
821 QwtLogTransform::LogMin, QwtLogTransform::LogMax );
822
823 if ( linearInterval.maxValue() / linearInterval.minValue() < logBase )
824 {
825 stepSize = 0.0;
826 return;
827 }
828 }
829
830 double logRef = 1.0;
831 if ( reference() > QwtLogTransform::LogMin / 2 )
832 logRef = qwtMinF( reference(), QwtLogTransform::LogMax / 2 );
833
834 if ( testAttribute( QwtScaleEngine::Symmetric ) )
835 {
836 const double delta = qwtMaxF( interval.maxValue() / logRef,
837 logRef / interval.minValue() );
838 interval.setInterval( logRef / delta, logRef * delta );
839 }
840
841 if ( testAttribute( QwtScaleEngine::IncludeReference ) )
842 interval = interval.extend( logRef );
843
844 interval = interval.limited( QwtLogTransform::LogMin, QwtLogTransform::LogMax );
845
846 if ( interval.width() == 0.0 )
847 interval = buildInterval( interval.minValue() );
848
849 stepSize = divideInterval( qwtLogInterval( logBase, interval ).width(),
850 qMax( maxNumSteps, 1 ) );
851 if ( stepSize < 1.0 )
852 stepSize = 1.0;
853
854 if ( !testAttribute( QwtScaleEngine::Floating ) )
855 interval = align( interval, stepSize );
856
857 x1 = interval.minValue();
858 x2 = interval.maxValue();
859
860 if ( testAttribute( QwtScaleEngine::Inverted ) )
861 {
862 qSwap( x1, x2 );
863 stepSize = -stepSize;
864 }
865 }
866
879 QwtScaleDiv QwtLogScaleEngine::divideScale( double x1, double x2,
880 int maxMajorSteps, int maxMinorSteps, double stepSize ) const
881 {
882 QwtInterval interval = QwtInterval( x1, x2 ).normalized();
883 interval = interval.limited( QwtLogTransform::LogMin, QwtLogTransform::LogMax );
884
885 if ( interval.width() <= 0 )
886 return QwtScaleDiv();
887
888 const double logBase = base();
889
890 if ( interval.maxValue() / interval.minValue() < logBase )
891 {
892 // scale width is less than one decade -> build linear scale
893
894 QwtLinearScaleEngine linearScaler;
895 linearScaler.setAttributes( attributes() );
896 linearScaler.setReference( reference() );
897 linearScaler.setMargins( lowerMargin(), upperMargin() );
898
899 return linearScaler.divideScale( x1, x2,
900 maxMajorSteps, maxMinorSteps, 0.0 );
901 }
902
903 stepSize = qAbs( stepSize );
904 if ( stepSize == 0.0 )
905 {
906 if ( maxMajorSteps < 1 )
907 maxMajorSteps = 1;
908
909 stepSize = divideInterval(
910 qwtLogInterval( logBase, interval ).width(), maxMajorSteps );
911 if ( stepSize < 1.0 )
912 stepSize = 1.0; // major step must be >= 1 decade
913 }
914
915 QwtScaleDiv scaleDiv;
916 if ( stepSize != 0.0 )
917 {
918 QList< double > ticks[QwtScaleDiv::NTickTypes];
919 buildTicks( interval, stepSize, maxMinorSteps, ticks );
920
921 scaleDiv = QwtScaleDiv( interval, ticks );
922 }
923
924 if ( x1 > x2 )
925 scaleDiv.invert();
926
927 return scaleDiv;
928 }
929
940 void QwtLogScaleEngine::buildTicks(
941 const QwtInterval& interval, double stepSize, int maxMinorSteps,
942 QList< double > ticks[QwtScaleDiv::NTickTypes] ) const
943 {
944 const QwtInterval boundingInterval = align( interval, stepSize );
945
946 ticks[QwtScaleDiv::MajorTick] =
947 buildMajorTicks( boundingInterval, stepSize );
948
949 if ( maxMinorSteps > 0 )
950 {
951 buildMinorTicks( ticks[QwtScaleDiv::MajorTick], maxMinorSteps, stepSize,
952 ticks[QwtScaleDiv::MinorTick], ticks[QwtScaleDiv::MediumTick] );
953 }
954
955 for ( int i = 0; i < QwtScaleDiv::NTickTypes; i++ )
956 ticks[i] = strip( ticks[i], interval );
957 }
958
967 QList< double > QwtLogScaleEngine::buildMajorTicks(
968 const QwtInterval& interval, double stepSize ) const
969 {
970 double width = qwtLogInterval( base(), interval ).width();
971
972 int numTicks = qRound( width / stepSize ) + 1;
973 if ( numTicks > 10000 )
974 numTicks = 10000;
975
976 const double lxmin = std::log( interval.minValue() );
977 const double lxmax = std::log( interval.maxValue() );
978 const double lstep = ( lxmax - lxmin ) / double( numTicks - 1 );
979
980 QList< double > ticks;
981 ticks.reserve( numTicks );
982
983 ticks += interval.minValue();
984
985 for ( int i = 1; i < numTicks - 1; i++ )
986 ticks += std::exp( lxmin + double( i ) * lstep );
987
988 ticks += interval.maxValue();
989
990 return ticks;
991 }
992
1002 void QwtLogScaleEngine::buildMinorTicks(
1003 const QList< double >& majorTicks,
1004 int maxMinorSteps, double stepSize,
1005 QList< double >& minorTicks,
1006 QList< double >& mediumTicks ) const
1007 {
1008 const double logBase = base();
1009
1010 if ( stepSize < 1.1 ) // major step width is one base
1011 {
1012 double minStep = divideInterval( stepSize, maxMinorSteps + 1 );
1013 if ( minStep == 0.0 )
1014 return;
1015
1016 const int numSteps = qRound( stepSize / minStep );
1017
1018 int mediumTickIndex = -1;
1019 if ( ( numSteps > 2 ) && ( numSteps % 2 == 0 ) )
1020 mediumTickIndex = numSteps / 2;
1021
1022 for ( int i = 0; i < majorTicks.count() - 1; i++ )
1023 {
1024 const double v = majorTicks[i];
1025 const double s = logBase / numSteps;
1026
1027 if ( s >= 1.0 )
1028 {
1029 if ( !qFuzzyCompare( s, 1.0 ) )
1030 minorTicks += v * s;
1031
1032 for ( int j = 2; j < numSteps; j++ )
1033 {
1034 minorTicks += v * j * s;
1035 }
1036 }
1037 else
1038 {
1039 for ( int j = 1; j < numSteps; j++ )
1040 {
1041 const double tick = v + j * v * ( logBase - 1 ) / numSteps;
1042 if ( j == mediumTickIndex )
1043 mediumTicks += tick;
1044 else
1045 minorTicks += tick;
1046 }
1047 }
1048 }
1049 }
1050 else
1051 {
1052 double minStep = divideInterval( stepSize, maxMinorSteps );
1053 if ( minStep == 0.0 )
1054 return;
1055
1056 if ( minStep < 1.0 )
1057 minStep = 1.0;
1058
1059 // # subticks per interval
1060 int numTicks = qRound( stepSize / minStep ) - 1;
1061
1062 // Do the minor steps fit into the interval?
1063 if ( qwtFuzzyCompare( ( numTicks + 1 ) * minStep,
1064 stepSize, stepSize ) > 0 )
1065 {
1066 numTicks = 0;
1067 }
1068
1069 if ( numTicks < 1 )
1070 return;
1071
1072 int mediumTickIndex = -1;
1073 if ( ( numTicks > 2 ) && ( numTicks % 2 ) )
1074 mediumTickIndex = numTicks / 2;
1075
1076 // substep factor = base^substeps
1077 const qreal minFactor = qwtMaxF( std::pow( logBase, minStep ), logBase );
1078
1079 for ( int i = 0; i < majorTicks.count(); i++ )
1080 {
1081 double tick = majorTicks[i];
1082 for ( int j = 0; j < numTicks; j++ )
1083 {
1084 tick *= minFactor;
1085
1086 if ( j == mediumTickIndex )
1087 mediumTicks += tick;
1088 else
1089 minorTicks += tick;
1090 }
1091 }
1092 }
1093 }
1094
1106 QwtInterval QwtLogScaleEngine::align(
1107 const QwtInterval& interval, double stepSize ) const
1108 {
1109 const QwtInterval intv = qwtLogInterval( base(), interval );
1110
1111 double x1 = QwtScaleArithmetic::floorEps( intv.minValue(), stepSize );
1112 if ( qwtFuzzyCompare( interval.minValue(), x1, stepSize ) == 0 )
1113 x1 = interval.minValue();
1114
1115 double x2 = QwtScaleArithmetic::ceilEps( intv.maxValue(), stepSize );
1116 if ( qwtFuzzyCompare( interval.maxValue(), x2, stepSize ) == 0 )
1117 x2 = interval.maxValue();
1118
1119 return qwtPowInterval( base(), QwtInterval( x1, x2 ) );
1120 }
QList< double >
QwtInterval
A class representing an interval.
Definition: qwt_interval.h:23
QwtInterval::setInterval
void setInterval(double minValue, double maxValue, BorderFlags=IncludeBorders)
Definition: qwt_interval.h:143
QwtInterval::minValue
double minValue() const
Definition: qwt_interval.h:192
QwtInterval::normalized
QwtInterval normalized() const
Normalize the limits of the interval.
Definition: qwt_interval.cpp:29
QwtInterval::width
double width() const
Return the width of an interval.
Definition: qwt_interval.h:227
QwtInterval::widthL
long double widthL() const
Return the width of an interval as long double.
Definition: qwt_interval.h:241
QwtInterval::setMaxValue
void setMaxValue(double)
Definition: qwt_interval.h:186
QwtInterval::maxValue
double maxValue() const
Definition: qwt_interval.h:198
QwtInterval::limited
QwtInterval limited(double lowerBound, double upperBound) const
Definition: qwt_interval.cpp:336
QwtInterval::extend
QwtInterval extend(double value) const
Extend the interval.
Definition: qwt_interval.cpp:363
QwtInterval::setMinValue
void setMinValue(double)
Definition: qwt_interval.h:176
QwtInterval::isValid
bool isValid() const
Definition: qwt_interval.h:210
QwtInterval::symmetrize
QwtInterval symmetrize(double value) const
Definition: qwt_interval.cpp:317
QwtLinearScaleEngine
A scale engine for linear scales.
Definition: qwt_scale_engine.h:152
QwtLinearScaleEngine::buildMinorTicks
void buildMinorTicks(const QList< double > &majorTicks, int maxMinorSteps, double stepSize, QList< double > &minorTicks, QList< double > &mediumTicks) const
Calculate minor/medium ticks for major ticks.
Definition: qwt_scale_engine.cpp:692
QwtLinearScaleEngine::autoScale
virtual void autoScale(int maxNumSteps, double &x1, double &x2, double &stepSize) const override
Definition: qwt_scale_engine.cpp:531
QwtLinearScaleEngine::buildTicks
void buildTicks(const QwtInterval &, double stepSize, int maxMinorSteps, QList< double > ticks[QwtScaleDiv::NTickTypes]) const
Calculate ticks for an interval.
Definition: qwt_scale_engine.cpp:627
QwtLinearScaleEngine::buildMajorTicks
QList< double > buildMajorTicks(const QwtInterval &interval, double stepSize) const
Calculate major ticks for an interval.
Definition: qwt_scale_engine.cpp:664
QwtLinearScaleEngine::QwtLinearScaleEngine
QwtLinearScaleEngine(uint base=10)
Definition: qwt_scale_engine.cpp:511
QwtLinearScaleEngine::~QwtLinearScaleEngine
virtual ~QwtLinearScaleEngine()
Destructor.
Definition: qwt_scale_engine.cpp:517
QwtLinearScaleEngine::divideScale
virtual QwtScaleDiv divideScale(double x1, double x2, int maxMajorSteps, int maxMinorSteps, double stepSize=0.0) const override
Calculate a scale division for an interval.
Definition: qwt_scale_engine.cpp:577
QwtLinearScaleEngine::align
QwtInterval align(const QwtInterval &, double stepSize) const
Align an interval to a step size.
Definition: qwt_scale_engine.cpp:741
QwtLogScaleEngine::buildMajorTicks
QList< double > buildMajorTicks(const QwtInterval &interval, double stepSize) const
Calculate major ticks for an interval.
Definition: qwt_scale_engine.cpp:967
QwtLogScaleEngine::buildMinorTicks
void buildMinorTicks(const QList< double > &majorTicks, int maxMinorSteps, double stepSize, QList< double > &minorTicks, QList< double > &mediumTicks) const
Calculate minor/medium ticks for major ticks.
Definition: qwt_scale_engine.cpp:1002
QwtLogScaleEngine::buildTicks
void buildTicks(const QwtInterval &, double stepSize, int maxMinorSteps, QList< double > ticks[QwtScaleDiv::NTickTypes]) const
Calculate ticks for an interval.
Definition: qwt_scale_engine.cpp:940
QwtLogScaleEngine::divideScale
virtual QwtScaleDiv divideScale(double x1, double x2, int maxMajorSteps, int maxMinorSteps, double stepSize=0.0) const override
Calculate a scale division for an interval.
Definition: qwt_scale_engine.cpp:879
QwtLogScaleEngine::QwtLogScaleEngine
QwtLogScaleEngine(uint base=10)
Definition: qwt_scale_engine.cpp:776
QwtLogScaleEngine::autoScale
virtual void autoScale(int maxNumSteps, double &x1, double &x2, double &stepSize) const override
Definition: qwt_scale_engine.cpp:797
QwtLogScaleEngine::align
QwtInterval align(const QwtInterval &, double stepSize) const
Align an interval to a step size.
Definition: qwt_scale_engine.cpp:1106
QwtLogScaleEngine::~QwtLogScaleEngine
virtual ~QwtLogScaleEngine()
Destructor.
Definition: qwt_scale_engine.cpp:783
QwtLogTransform
Logarithmic transformation.
Definition: qwt_transform.h:101
QwtLogTransform::LogMax
static const double LogMax
Largest allowed value for logarithmic scales: 1.0e150.
Definition: qwt_transform.h:114
QwtLogTransform::LogMin
static const double LogMin
Smallest allowed value for logarithmic scales: 1.0e-150.
Definition: qwt_transform.h:113
QwtScaleArithmetic::divideEps
static double divideEps(double intervalSize, double numSteps)
Divide an interval into steps.
Definition: qwt_scale_engine.cpp:143
QwtScaleArithmetic::ceilEps
static double ceilEps(double value, double intervalSize)
Definition: qwt_scale_engine.cpp:108
QwtScaleArithmetic::floorEps
static double floorEps(double value, double intervalSize)
Definition: qwt_scale_engine.cpp:126
QwtScaleArithmetic::divideInterval
static double divideInterval(double intervalSize, int numSteps, uint base)
Definition: qwt_scale_engine.cpp:160
QwtScaleDiv
A class representing a scale division.
Definition: qwt_scale_div.h:34
QwtScaleDiv::invert
void invert()
Definition: qwt_scale_div.cpp:224
QwtScaleDiv::MediumTick
@ MediumTick
Medium ticks.
Definition: qwt_scale_div.h:46
QwtScaleDiv::MinorTick
@ MinorTick
Minor ticks.
Definition: qwt_scale_div.h:43
QwtScaleDiv::NTickTypes
@ NTickTypes
Number of valid tick types.
Definition: qwt_scale_div.h:52
QwtScaleDiv::MajorTick
@ MajorTick
Major ticks.
Definition: qwt_scale_div.h:49
QwtScaleEngine
Base class for scale engines.
Definition: qwt_scale_engine.h:46
QwtScaleEngine::transformation
QwtTransform * transformation() const
Definition: qwt_scale_engine.cpp:265
QwtScaleEngine::reference
double reference() const
Definition: qwt_scale_engine.cpp:474
QwtScaleEngine::Attributes
QFlags< Attribute > Attributes
Definition: qwt_scale_engine.h:78
QwtScaleEngine::QwtScaleEngine
QwtScaleEngine(uint base=10)
Definition: qwt_scale_engine.cpp:222
QwtScaleEngine::strip
QList< double > strip(const QList< double > &, const QwtInterval &) const
Definition: qwt_scale_engine.cpp:364
QwtScaleEngine::Attribute
Attribute
Definition: qwt_scale_engine.h:55
QwtScaleEngine::Floating
@ Floating
Definition: qwt_scale_engine.h:72
QwtScaleEngine::Inverted
@ Inverted
Turn the scale upside down.
Definition: qwt_scale_engine.h:75
QwtScaleEngine::NoAttribute
@ NoAttribute
No attributes.
Definition: qwt_scale_engine.h:57
QwtScaleEngine::Symmetric
@ Symmetric
Build a scale which is symmetric to the reference() value.
Definition: qwt_scale_engine.h:63
QwtScaleEngine::IncludeReference
@ IncludeReference
Build a scale which includes the reference() value.
Definition: qwt_scale_engine.h:60
QwtScaleEngine::divideInterval
double divideInterval(double intervalSize, int numSteps) const
Definition: qwt_scale_engine.cpp:326
QwtScaleEngine::upperMargin
double upperMargin() const
Definition: qwt_scale_engine.cpp:291
QwtScaleEngine::contains
bool contains(const QwtInterval &, double value) const
Definition: qwt_scale_engine.cpp:341
QwtScaleEngine::testAttribute
bool testAttribute(Attribute) const
Definition: qwt_scale_engine.cpp:431
QwtScaleEngine::buildInterval
QwtInterval buildInterval(double value) const
Build an interval around a value.
Definition: qwt_scale_engine.cpp:395
QwtScaleEngine::setReference
void setReference(double)
Specify a reference point.
Definition: qwt_scale_engine.cpp:465
QwtScaleEngine::~QwtScaleEngine
virtual ~QwtScaleEngine()
Destructor.
Definition: qwt_scale_engine.cpp:230
QwtScaleEngine::lowerMargin
double lowerMargin() const
Definition: qwt_scale_engine.cpp:280
QwtScaleEngine::setAttributes
void setAttributes(Attributes)
Definition: qwt_scale_engine.cpp:442
QwtScaleEngine::setAttribute
void setAttribute(Attribute, bool on=true)
Definition: qwt_scale_engine.cpp:417
QwtScaleEngine::setTransformation
void setTransformation(QwtTransform *)
Definition: qwt_scale_engine.cpp:248
QwtScaleEngine::base
uint base() const
Definition: qwt_scale_engine.cpp:500
QwtScaleEngine::attributes
Attributes attributes() const
Definition: qwt_scale_engine.cpp:451
QwtScaleEngine::setMargins
void setMargins(double lower, double upper)
Specify margins at the scale's endpoints.
Definition: qwt_scale_engine.cpp:312
QwtScaleEngine::setBase
void setBase(uint base)
Definition: qwt_scale_engine.cpp:491
QwtTransform
A transformation between coordinate systems.
Definition: qwt_transform.h:36