Qt绘制曲线

引言

应易和仓储系统需求,使运输车在行驶过程与刹车过程中运行得平稳,下位机通过无极变速控制应运而生,而上位机的无极变速参数设置也必不可少。这就用到了Qt的绘制曲线。

Qt的图形界面很厉害,之前的项目中用到的都是Qt的一些简单的应用,通过绘制曲线才对Qt的图形有了初步的了解。原来我也可以画出美丽平滑的余弦曲线。

1 坐标转换

(1)坐标系的认识

在绘制曲线之前,先要对坐标系有个深入的认识。如果对坐标系认识模糊,那么在绘制曲线时对于点的坐标也将是一团浆糊,更谈不上画出符合一定函数的曲线了。

在无极变速参数设置中,有三个坐标系,我把它们称为:世界坐标,屏幕坐标,窗口坐标。

世界坐标就是类似s(距离)--t(时间),v(速度)--t(时间)等坐标系。我们希望的是绘制出相应的函数曲线。

窗口坐标实际上是Qt的窗口坐标,显示的都是一个一个像素,单位是像素。另外,需注意的是Qt的窗口坐标是x向右y向下生长的,与数学中经常接触到的x向右y向上不太一样。

屏幕坐标是什么呢?可以认为是在窗口坐标中抠出一部分区域,在这个区域中绘制出肉眼看到的坐标系和曲线。单位也是像素。

但是Qt是只认识窗口坐标的。如何将无极变速中的速度(或频率),距离的函数关系描述出来,就需要将相应的世界坐标转换成相应的屏幕坐标,再将相应的屏幕坐标转换成窗口坐标显示。

当然,这3个坐标系只是当前应用所需,还可以继续推广。其他应用可能需要的坐标系转换更多,可能是5个(据说码垛机中的机器视觉识别就有5个坐标系)甚至更多。

(2)坐标系的转换

屏幕坐标-->窗口坐标​

 

首先应明确的是窗口坐标中的总长度winWidth和总高度winHeigth。

winWidth = this->width();

winHeight = this->height();

那屏幕坐标最好在左右预留出xOff ,在上下预留出yOff 。也是对称美,也是为了标出x和y上的刻度。屏幕坐标的总长度scWidth和总高度scHeight也就有了。

scWidth = winWidth-2*xOff; //事先定义的xOff ,yOff

scHeight = winHeight-2*yOff;

接下来就可以推算屏幕坐标和窗口坐标的对应关系了。

 

由上图可以得到:屏幕坐标sPoint与窗口坐标qPoint的关系是

//屏幕坐标转换为窗口坐标

void sc2qc(QPoint& sPoint,QPoint &qPoint)

{

qPoint.setX(sPoint.x()+xOff);

qPoint.setY(winHeight-yOff-sPoint.y());

}

世界坐标-->屏幕坐标

类似比例尺的缩放一样,将世界坐标缩放成屏幕坐标,x向y向自是有各自的比例系数kx,ky。如果世界坐标中x方向的范围是xRange ,y方向的范围是yRange 。

kx=scWidth/xRange;

ky=scHeight/yRange;

世界坐标中任意一点(xw,yw)转换成屏幕坐标中的一点sPoint时,乘以对应的比例系数即可。

void wc2sc(double xw,double yw,QPoint& sPoint)

{

double x =xw*kx;

double y = yw*ky;

//如果x和y都是double类型,就需要将其转换成int类型,因为Point类的x和y是像素,只能是int类型。那么double转换成int需要注意(我好像一直都没弄明白过)

if(x>=0)sPoint.setX(x+0.5);

else sPoint.setX(x-0.5);

if(y>=0)sPoint.setY(y+0.5);

else sPoint.setY(y-0.5);

}

至此,就搞清楚了3个坐标系中对应坐标的转换了。

2 绘制坐标轴

三个点,两条直线确定两个坐标轴,三个点xePoint, originPoint, yePoint均是屏幕坐标下的点,画直线时都要转换成窗口坐标才行。根据xePoint和yePoint可以确定两坐标轴端处的两个空心三角形。这样,坐标轴就大致画好了。

接下来绘制坐标轴上的刻度线。这也是个体力活,不过自从弄清楚坐标系的转换后,这都是个容易的事情。把屏幕坐标像素总长度scWidth平均分成几段(xSpaces),像素总高度scHeight平均分成几段(ySpaces),找到x向各个刻度线的坐标,y向各个刻度线的坐标,再drawLine()就可以。道理很简单,画起来有许多细节要留心。比如,不用一个一个刻度线去找坐标,只是两个循环;要将刻度线都画成虚线,看起来更漂亮,也是需要设置相应的格式的。

xGridPixel=scWidth/xSpaces;

yGridPixel=scHeight/ySpaces;

void FuncWidget::drawXGrid(int n)

{

//设置刻度线为虚线

painter->setPen(Qt::white);

painter->setPen(Qt::DashLine);

//刻度线上两点

QPoint xGridPoint(n*xGridPixel,0);

QPoint xGridTopPoint(n*xGridPixel,scHeight);

QPoint xGridPointQt;

QPoint xGridTopPointQt;

//屏幕坐标转换成窗口坐标

sc2qc(xGridPoint,xGridPointQt);

sc2qc(xGridTopPoint,xGridTopPointQt);

//绘制刻度线

painter->drawLine(xGridPointQt,xGridTopPointQt);

//写上刻度

QPoint textPoint=xGridPoint+QPoint(-20,-20);

QPoint textPointQt;

sc2qc(textPoint,textPointQt);

painter->drawText(textPointQt,tr("%1").arg(xRange/xSpaces*n));

}

for(int n=0;n<=xSpaces;n++) //xSpaces可随意设置

{

drawXGrid(n);

}

//y向也类似,就不一一列举。

3 绘制曲线

各种准备工作做完后,这才进入到刻画数学函数关系的时刻了。

先来缕清数学函数关系y=f(x) ,这里f 可以是刻画直线y=k*x+b的数学函数,也可以是刻画余弦曲线y=cos(x)的数学函数。依据自己应用需要而定。我要实现的正是直线和余弦曲线的绘制。

设置这样一个表示数学函数关系的函数,这句话中有两个函数,一个是数学中常用的数学函数,一个是程序语言中类的成员函数。这个成员函数为double f(int mode,int x);表示直线模式和曲线模式下由x得到y。

如果是直线函数,由k和b即得到y;如果是余弦函数,由标准库函数可得到x对应的余弦值或反余弦值。

取尽xRange范围内的所有x值,得到对应的所有的y值,会得到有限个对应数学函数关系的点,然后由x和y值会用到世界坐标向屏幕坐标的转换,得到转换后的点,依次连接这些点,就会绘制出对应的曲线。

QWidget有个信号槽函数update() ,当update()被调用时,会自动调用void paintEvent(QPaintEvent *)事件。所以绘制工作都在这个函数中实现。

在此之前,在构造函数中新建一个painter=new QPainter;再painter->begin(this);将坐标轴,刻度线,曲线都在其中绘制。最后painter->end();就完成了绘制。

绘制的直线和曲线如下:​

 

4 注意事项

1 double和int 的转换

double-->int :

可以用标准库中的round(x)函数,即取得x的四舍五入的整数值。

也可以如下:

double x;

int xi;

if(x>=0)xi=(x+0.5);

else xi=(x-0.5);

int-->double:

可以转换时在要转换的数前加double,也可以把数学符号前面或后面的某个数前做double转换。double w=2*(x-minHz); w-=1.0;

2 调用标准库函数

#include "stdio.h"

using namespace std;

#include "math.h"

double y=cos(x);


网址:http://blog.sina.com.cn/s/blog_9542b5c70102veg5.html

  • 6
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: 在C++和Qt中,绘制曲线图可以使用Qt中的QCustomPlot库来实现。QCustomPlot是一个强大的绘图库,提供了丰富的绘图功能,包括曲线图、柱状图、散点图等。 要绘制曲线图,首先需要创建一个QCustomPlot对象,并将其添加到QWidget或QMainWindow上。然后,我们可以使用QCustomPlot的函数来设置图表的标题、坐标轴标签和范围等属性。 接下来,可以创建一个QCPGraph对象,用于绘制曲线。通过设置QCPGraph的数据和颜色等属性,可以完成曲线绘制。我们可以使用QCustomPlot的函数来添加和删除曲线。 在绘制曲线之前,需要准备好曲线的数据。通常,我们可以将曲线的数据存储在一个Qt容器(如QVector)中,然后将其传递给QCPGraph的setData函数。 一旦准备好曲线的数据和属性,即可调用QCustomPlot的replot函数来重新绘制曲线图。曲线图会根据传递给setData函数的数据自动更新和调整。 除了基本的曲线绘制外,QCustomPlot还提供了许多其他功能,如坐标轴刻度的设置、网格线的显示、多曲线绘制等。通过研究QCustomPlot的文档和示例代码,可以更深入地了解和使用它的功能。 总之,使用C++和Qt绘制曲线图是相对简单的。通过使用QCustomPlot库,我们可以方便地实现曲线绘制和操控。 ### 回答2: 在C++中使用Qt绘制曲线图可以通过QCustomPlot库来实现。以下是实现步骤: 1. 安装QCustomPlot库:将QCustomPlot的源代码添加到项目中,并在项目文件的.pro文件中添加库的引用。 2. 创建曲线图窗口:使用QMainWindow或QWidget派生类创建一个窗口用于显示曲线图。 3. 初始化曲线图:在窗口的构造函数中,创建一个QCustomPlot对象,并设置图表的标题、坐标轴等属性。 4. 添加数据:使用QVector保存曲线图的数据点,并将其添加到QCustomPlot对象中。 5. 绘制曲线图:使用QCustomPlot的addGraph()方法创建曲线,并将数据点设置为曲线的坐标。 6. 设置曲线样式:使用QPen类设置曲线的颜色、线型等样式。 7. 显示曲线图:使用QCustomPlot的replot()方法将曲线绘制在窗口上。 8. 添加交互功能:如果需要,可以通过QCustomPlot的信号和槽机制,实现交互功能,例如缩放、平移等。 9. 更新曲线图:如果需要在运行期间更新曲线图,可以通过重新设置数据点的方式,再次调用replot()方法进行更新。 10. 清除曲线图:如果需要清除曲线图,可以调用QCustomPlot的clearGraphs()方法清除所有曲线。 总结:使用Qt的QCustomPlot库可以方便地绘制曲线图。通过初始化、添加数据、绘制曲线、设置样式、显示曲线、添加交互功能、更新和清除曲线等步骤,可以实现自定义的曲线绘制。 ### 回答3: C++和Qt是一种常用的编程语言和开发工具,可以用于绘制曲线图。Qt是一个跨平台的开发框架,具有丰富的功能和易用的API,可以轻松地绘制各种图形,包括曲线图。 要使用Qt绘制曲线图,首先需要创建一个窗口或视图来展示图形。可以使用Qt的窗口类(如QMainWindow、QWidget)或图形视图类(如QGraphicsView、QChartView)来创建一个可显示图形的界面。 然后,需要创建一个曲线图对象(如QLineSeries、QSplineSeries),并且添加数据点到曲线上。Qt提供了数据序列类来存储数据,以便绘制曲线图。可以使用append方法向序列对象中添加数据点。 接下来,需要创建一个图表对象(如QChart),将曲线图对象添加到图表中,并设置图表的样式和属性,如标题、坐标轴等。Qt提供了一系列的图表类,来帮助我们创建具有各种样式的图表。 最后,将图表对象添加到窗口或视图中,并显示出来。可以使用布局管理器(如QVBoxLayout、QGridLayout)将图表放置在窗口或视图中的合适位置,然后调用show()方法显示出来。 在绘制曲线图时,还可以根据需要自定义曲线的样式和属性,如线条颜色、线宽等。可以使用Qt的绘图API来绘制曲线,如设置笔(QPen)的颜色和宽度。 绘制曲线图是一个需要一定编程知识和经验的任务,但使用Qt可以简化这个过程,提供了丰富的功能和易用的API,使曲线图的绘制变得容易和灵活。通过学习和熟悉Qt的绘图功能,我们可以更加方便地创建出漂亮的曲线图。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值