1. 概述
在Qwt中,QwtScaleMap所占的地位是相当重要的,几乎涵盖了Qwt绘图系统的任何角落。因此在这里将对该类的用法,与原理(自己的理解)进行整理。
本系列所使用源码版本:qwt-6.1.4。
2. 定义
/*!
\brief A scale map
QwtScaleMap offers transformations from the coordinate system
of a scale into the linear coordinate system of a paint device
and vice versa.
*/
源码注释该类的作用:一个比例尺映射。QwtScaleMap类提供比例尺坐标系统向线性的绘图设备坐标系统的转换,反之亦然。
比例尺坐标系统:在对坐标轴的比例尺设置完区间值后:
QwtPlot:
void setAxisScale( int axisId, double min, double max, double stepSize = 0 );
系统调用
QwtScaleEngine:
virtual void autoScale( int maxNumSteps, double &x1, double &x2, double &stepSize ) const = 0;
virtual QwtScaleDiv divideScale( double x1, double x2, int maxMajorSteps, int maxMinorSteps, double stepSize = 0.0 ) const = 0;
更新比例尺的区间刻度值。
线性的绘图设备坐标系统:这个坐标最多的就是窗口坐标系统,在Qwt中大多是QFrame。
说白了,这个类的作用就是讲用户设置的坐标轴的区间值,转换到窗口坐标系中去,在绘制或更新坐标轴时,可以在窗口坐标系统中找到正确的绘制位置。
3. 重要的成员变量
- 比例尺边界区间
double d_s1, d_s2; // scale interval boundaries
- 绘图设备边界区间
double d_p1, d_p2; // paint device interval boundaries
- 转换因子
double d_cnv; // conversion factor
4. 重要的函数
void QwtScaleMap::updateFactor()
{
d_ts1 = d_s1;
double ts2 = d_s2;
if ( d_transform )
{
d_ts1 = d_transform->transform( d_ts1 );
ts2 = d_transform->transform( ts2 );
}
d_cnv = 1.0;
if ( d_ts1 != ts2 )
d_cnv = ( d_p2 - d_p1 ) / ( ts2 - d_ts1 );
}
d_cnv:设备区间与转换之后的比例尺区间之间的比例。一个设备值,对应多少个比例尺值。默认为1比1。
- 转换一个值
inline double QwtScaleMap::transform( double s ) const
{
if ( d_transform )
s = d_transform->transform( s );
return d_p1 + ( s - d_ts1 ) * d_cnv;
}
s为刻度值,首先将s转换到设备坐标系,返回该值在设备坐标系中的位置值。
- 反转换一个值
inline double QwtScaleMap::invTransform( double p ) const
{
double s = d_ts1 + ( p - d_p1 ) / d_cnv;
if ( d_transform )
s = d_transform->invTransform( s );
return s;
}
反向转换,p为设备点值,将设备点值转换成比例尺值,再将比例尺值转换为比例尺显示值。
- 转换一个点或多个点
相对于一个值来说,点(QPointF)包含两个维度,即两个坐标轴。区域(QRectF)也包含两个坐标轴。
函数接口如下:
static QRectF transform( const QwtScaleMap &, const QwtScaleMap &, const QRectF & );
static QRectF invTransform( const QwtScaleMap &, const QwtScaleMap &, const QRectF & );
static QPointF transform( const QwtScaleMap &, const QwtScaleMap &, const QPointF & );
static QPointF invTransform( const QwtScaleMap &, const QwtScaleMap &, const QPointF & );
函数接口虽然是QwtScaleMap的public接口。但是函数内部并没有直接访问类的其他成员。
5. 总结
QwtScaleMap类更像是一个转换适配器,将坐标轴值转换到可绘制的绘制设备(窗口)上。