QT之qwtplot3d使用(一)

您所在的位置:网站首页 3dmax画线条怎么画曲线视频教程 QT之qwtplot3d使用(一)

QT之qwtplot3d使用(一)

2024-07-17 01:40| 来源: 网络整理| 查看: 265

QT之qwtplot3d使用(一) qwtplot3d 简介

qwtplot3d是qt解决三维图形绘制的库,核心通过调用openGL库完成,可以实现三维曲面绘制,三维状态下折线,散点等图形的绘制。但是其在十多年前推出后一直没有太大的更新,而且自带的类并不够丰富,所以在使用时还是有一些问题的。主要参考了引用1中的博客,qwtplot3d库的代码在该博主的博客中可以下载到,另外在github中搜索qwtplot3d,找到标星最多的一个,但是该库有改动,另外可以在引用2中下载到官方库文件。

使用qwtplot3d画线

参考QWT3D 之 三维动态曲线的实现

画线的实现原理是改变了在各个顶点之间画图形的方式,由之前的画三维曲面改成直接将前后点相连。我使用的是从博主那里下载到的源码,其中的Line3D类已经写好,在qwt3d_enrichment_std.cpp中,我们看一下该类:

class QWT3D_EXPORT Line3D: public VertexEnrichment { public: Line3D(); Line3D(double thick,bool smooth); Qwt3D::Enrichment * clone() const{ return new Line3D(*this);} void configure(double thick, bool smooth); void drawBegin(); void drawEnd(); virtual void draw(Qwt3D::Triple const&); virtual void draw(); virtual void add(Qwt3D::Triple const & t); virtual void setLineColor(RGBA color); /*virtual void clear() { lineData.clear(); //myColorMap.clear(); }*/ //virtual void setLineColor(int startIndex,RGBA color); // virtual void setLineColor(RGBA color); //virtual RGBA getColor(int pointIndex); private: bool smooth_; double lineThick; GLboolean oldstate_; std::vector lineData; RGBA rgba; //std::map myColorMap; };

该类中主要几个成员变量,double lineThick代表线的粗细;bool smooth_ 代表是否光滑,在点数较多时可能会出现显示问题,如果因为点数太多导致显示的图形颜色发挥可以将改变量设为false,点的形状会变成方形,但是颜色更加清晰;RGBA rgba; 是线的颜色,有r,g,b,a四个成员变量,都是double型,rgb合成一个颜色,a为透明度,不透明为1,rgb取值为0-1。std::vectorQwt3D::Triple lineData是折线顶点的向量,元素Qwt3D::Triple有x,y,z三个成员变量,是个三维坐标,画线操作即是读取lineData中的三维坐标按顺序画线。函数方面,configure 可以改变线的粗细和是否光滑,add 函数可以向lineData向量中添加一个坐标点,setLineColor 设置颜色,剩下的就是和实际画图相关的函数,使用时调用draw() 即可,它会调用其它几个画图相关函数,把lineData画完。我们看一下draw() 函数

void Qwt3D::Line3D::drawBegin() { setDeviceLineWidth(lineThick); oldstate_ = glIsEnabled(GL_LINE_SMOOTH); if (smooth_) glEnable(GL_LINE_SMOOTH); else glDisable(GL_LINE_SMOOTH); //glPointSize(10); glBegin( GL_LINE_STRIP); } void Qwt3D::Line3D::drawEnd() { glEnd(); if (oldstate_) glEnable(GL_LINE_SMOOTH); else glDisable(GL_LINE_SMOOTH); } void Qwt3D::Line3D::draw(Qwt3D::Triple const& pos) { glColor4d(rgba.r,rgba.g,rgba.b,rgba.a); glVertex3d(pos.x,pos.y,pos.z); } void Qwt3D::Line3D::draw() { for (int i = 0; i < lineData.size(); i ++) { //RGBA rgba = getColor(i); //glColor4d(rgba.r,rgba.g,rgba.b,rgba.a); draw(lineData[i]); } }

通过这几个函数,最终调用了openGL库中的函数实现了折线的绘制。

使用qwtplot画点

实现画线之后,又需要用到画点功能,即绘制散点图。根据画线的实现原理,画点只需要将调用的openGL库函数改变即可,正好在qwtplot3d_enrichment_std.cpp有了一个Dot类用来实现画点,我们看一下原来的Dot类:

/ // // Dot // / Dot::Dot() { configure(1, false); } Dot::Dot(double pointsize, bool smooth) { configure(pointsize, smooth); } void Dot::configure(double pointsize, bool smooth) { plot = 0; pointsize_ = pointsize; smooth_ = smooth; } void Dot::drawBegin() { setDevicePointSize( pointsize_ ); oldstate_ = glIsEnabled(GL_POINT_SMOOTH); if (smooth_) glEnable(GL_POINT_SMOOTH); else glDisable(GL_POINT_SMOOTH); //glPointSize(10); glBegin( GL_POINTS ); } void Dot::drawEnd() { glEnd(); if (oldstate_) glEnable(GL_POINT_SMOOTH); else glDisable(GL_POINT_SMOOTH); } void Dot::draw(Qwt3D::Triple const& pos) { RGBA rgba = (*plot->dataColor())(pos); glColor4d(rgba.r,rgba.g,rgba.b,rgba.a); glVertex3d( pos.x, pos.y, pos.z); }

对比Line3D的实现,可以看出主要区别在drawBegin 和drawEnd 两个函数的设置,为了实现调用方式的统一,我对Dot类进行了修改,使其在格式上与Line3D相同,代码如下:

.H class QWT3D_EXPORT Dot : public VertexEnrichment { public: Dot(); Dot(double pointsize, bool smooth); Qwt3D::Enrichment* clone() const {return new Dot(*this);} void configure(double thick, bool smooth); void drawBegin(); void drawEnd(); void draw(Qwt3D::Triple const&); virtual void draw(); virtual void add(Qwt3D::Triple const & t); virtual void setLineColor(RGBA color); private: bool smooth_; double lineThick; GLboolean oldstate_; std::vector lineData; RGBA rgba; }; .CPP / // // Dot // / /* Dot::Dot() { configure(1, false); } Dot::Dot(double pointsize, bool smooth) { configure(pointsize, smooth); } void Dot::configure(double pointsize, bool smooth) { plot = 0; pointsize_ = pointsize; smooth_ = smooth; } void Dot::drawBegin() { setDevicePointSize( pointsize_ ); oldstate_ = glIsEnabled(GL_POINT_SMOOTH); if (smooth_) glEnable(GL_POINT_SMOOTH); else glDisable(GL_POINT_SMOOTH); //glPointSize(10); glBegin( GL_POINTS ); } void Dot::drawEnd() { glEnd(); if (oldstate_) glEnable(GL_POINT_SMOOTH); else glDisable(GL_POINT_SMOOTH); } void Dot::draw(Qwt3D::Triple const& pos) { RGBA rgba = (*plot->dataColor())(pos); glColor4d(rgba.r,rgba.g,rgba.b,rgba.a); glVertex3d( pos.x, pos.y, pos.z); } */ Qwt3D::Dot::Dot() { rgba.a = 1; rgba.b = 0.3; rgba.r = 0.6; rgba.g = 1; } Qwt3D::Dot::Dot(double thick,bool smooth) { lineThick = thick; smooth_ = smooth; rgba.a = 1; rgba.b = 0.3; rgba.r = 0.6; rgba.g = 1; } void Qwt3D::Dot::configure(double thick, bool smooth) { lineThick = thick; smooth_ = smooth; } void Qwt3D::Dot::drawBegin() { setDevicePointSize(lineThick); oldstate_ = glIsEnabled(GL_POINT_SMOOTH); if (smooth_) glEnable(GL_POINT_SMOOTH); else glDisable(GL_POINT_SMOOTH); //glPointSize(10); glBegin( GL_POINTS); } void Qwt3D::Dot::drawEnd() { glEnd(); if (oldstate_) glEnable(GL_POINT_SMOOTH); else glDisable(GL_POINT_SMOOTH); } void Qwt3D::Dot::draw(Qwt3D::Triple const& pos) { glColor4d(rgba.r,rgba.g,rgba.b,rgba.a); glVertex3d(pos.x,pos.y,pos.z); } void Qwt3D::Dot::draw() { for (int i = 0; i < lineData.size(); i ++) { //RGBA rgba = getColor(i); //glColor4d(rgba.r,rgba.g,rgba.b,rgba.a); draw(lineData[i]); } } void Qwt3D::Dot::add(Qwt3D::Triple const & t) { lineData.push_back(t); } void Qwt3D::Dot::setLineColor(RGBA color) { this->rgba = color; } draw()函数的调用

修改之后,对画线和画点的实现都可以通过调用相应类的draw() 函数实现。对该函数的调用在qwt3d_surfaceplot.cpp中,看下修改后的代码:

void SurfacePlot::createEnrichment(Enrichment& p) { // printf("createEnrichment\n"); if (!actualData_p) return; //todo future work if (p.type() != Enrichment::VERTEXENRICHMENT) return; p.assign(*this); p.drawBegin(); /* VertexEnrichment* ve = (VertexEnrichment*)&p; if (actualData_p->datatype == Qwt3D::POLYGON) { for (unsigned i = 0; i != actualDataC_->normals.size(); ++i) ve->draw(actualDataC_->nodes[i]); } else if (actualData_p->datatype == Qwt3D::GRID &&plotStyle() != Qwt3D::LINE3D_STYLE ) { int step = resolution(); for (int i = 0; i columns() - step; i += step) for (int j = 0; j rows() - step; j += step) ve->draw(Triple(actualDataG_->vertices[i][j][0], actualDataG_->vertices[i][j][1], actualDataG_->vertices[i][j][2])); } else if (plotStyle() == Qwt3D::LINE3D_STYLE) {*/ // printf("pdraw\n"); p.draw(); // } p.drawEnd(); }

原先的该函数时通过判断类的类型来调用不同绘制函数的,Qwt3D::LINE3D_STYLE等时枚举值,但是测试发现该判断没有生效,索性直接注释掉,保留了统一的p.draw()函数调用,这也是我把Dot类修改成与Line3D类格式相似的原因,不同的绘制方式在自己类中的draw()函数中实现。

小结

为了实现画线和画点功能,对于qwtplot3d库的修改就分享到这里,之后会写库函数调用和界面方面的问题。

qwtplot3d第二篇: QT之qwtplot3d使用(二)

引用

QWT3D 之 三维动态曲线的实现 qwtplot3d官方库 github中的qwtplot库



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3