Qt繪製曲線

2021-07-16 22:30:32 字數 3298 閱讀 4164

應易和倉儲系統需求,使運輸車在行駛過程與剎車過程中執行得平穩,下位機通過無極變速控制應運而生,而上位機的無極變速引數設定也必不可少。這就用到了qt的繪製曲線。

qt的圖形介面很厲害,之前的專案中用到的都是qt的一些簡單的應用,通過繪製曲線才對qt的圖形有了初步的了解。原來我也可以畫出美麗平滑的余弦曲線。

(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)

世界座標-->螢幕座標

類似比例尺的縮放一樣,將世界座標縮放成螢幕座標,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)

至此,就搞清楚了3個座標系中對應座標的轉換了。

三個點,兩條直線確定兩個座標軸,三個點xepoint, originpoint, yepoint均是螢幕座標下的點,畫直線時都要轉換成視窗座標才行。根據xepoint和yepoint可以確定兩座標軸端處的兩個空心三角形。這樣,座標軸就大致畫好了。

接下來繪製座標軸上的刻度線。這也是個體力活,不過自從弄清楚座標系的轉換後,這都是個容易的事情。把螢幕座標畫素總長度scwidth平均分成幾段(xspaces),畫素總高度scheight平均分成幾段(yspaces),找到x向各個刻度線的座標,y向各個刻度線的座標,再drawline()就可以。道理很簡單,畫起來有許多細節要留心。比如,不用乙個乙個刻度線去找座標,只是兩個迴圈;要將刻度線都畫成虛線,看起來更漂亮,也是需要設定相應的格式的。

xgridpixel=scwidth/xspaces;

ygridpixel=scheight/yspaces;

void funcwidget::drawxgrid(int n)

for(int n=0;n<=xspaces;n++) //xspaces可隨意設定

//y向也類似,就不一一枚舉。

各種準備工作做完後,這才進入到刻畫數學函式關係的時刻了。

先來縷清數學函式關係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();就完成了繪製。

繪製的直線和曲線如下:​

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);

**:

Qt 繪製平滑Bezier曲線

1 二階bezier static qpointf quadvalue const qpointf p0,const qpointf p1,const qpointf p2,qreal t static qpointf quadderived const qpointf p0,const qpoin...

Qt繪製動態曲線

ifndef qlinewidget h define qlinewidget h include include include include include include include include include include include include include incl...

qt5 QCharts使用 繪製曲線步驟

step qt core gui sql charts2.建立qchartview只需在生成的mainwindow.cpp中新增以下四行 就完成了qchartview的建立。include mainwindow.h include ui mainwindow.h include 手動新增 行1 us...