如何合并两个QwtScaleMap对象以简化坐标转换操作?
合并两个QwtScaleMap的方案
QwtScaleMap默认采用线性映射,连续两次transform调用本质是复合线性变换,我们可以通过计算复合后的映射区间,直接生成一个新的QwtScaleMap,只需一次transform就能完成原两次调用的效果。
具体步骤
- 确定合并后映射的源区间(Scale Interval):直接复用第二个ScaleMap的源区间,因为原流程是先将输入值转换到第二个ScaleMap的输出区间,再作为第一个ScaleMap的输入。
- 计算合并后映射的目标区间(Paint Interval):用第一个ScaleMap分别转换第二个ScaleMap目标区间的两端值,得到的结果就是合并后的目标区间。
- 创建新的QwtScaleMap,设置上述两个区间即可。
代码实现
#include <QCoreApplication> #include <QProcess> #include "qwt_scale_map.h" int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); QwtScaleMap scaleMapFirst; scaleMapFirst.setScaleInterval(0, 1); scaleMapFirst.setPaintInterval(49, 0); QwtScaleMap scaleMapSecond; scaleMapSecond.setScaleInterval(-3, 3); scaleMapSecond.setPaintInterval(0, 1); // 合并两个ScaleMap QwtScaleMap mergedScaleMap; // 设置合并后的源区间:复用第二个Map的源区间 mergedScaleMap.setScaleInterval(scaleMapSecond.scaleInterval().lowerBound(), scaleMapSecond.scaleInterval().upperBound()); // 设置合并后的目标区间:用第一个Map转换第二个Map的目标区间两端 double paintStart = scaleMapFirst.transform(scaleMapSecond.paintInterval().lowerBound()); double paintEnd = scaleMapFirst.transform(scaleMapSecond.paintInterval().upperBound()); mergedScaleMap.setPaintInterval(paintStart, paintEnd); // 测试转换结果,与原两次调用对比 double input = 1.194; double originalResult = scaleMapFirst.transform(scaleMapSecond.transform(input)); double mergedResult = mergedScaleMap.transform(input); qDebug() << "原两次调用结果:" << originalResult; qDebug() << "合并后调用结果:" << mergedResult; return a.exec(); }
补充说明
- 如果你的ScaleMap使用了非线性变换(比如通过
setTransformation自定义变换),这种直接映射区间的方式不适用,需要手动复合两个变换函数的逻辑。 - 代码中改用栈对象替代堆对象,避免不必要的内存泄漏,同时保持功能一致。
内容的提问来源于stack exchange,提问作者Juze
相关产品推荐
相关产品推荐

