1、qwtplot3d简介
qwtplot3d是一个用来绘制三维曲面的库
用来绘制空间曲线需要对库函数进行修改,由于本人的项目只需要绘制三维曲线,故对库函数的修改可能导致曲面绘制功能的缺失。及供参考。
2、库函数修改
参考该博主的例程QWT3D 之 三维动态曲线的实现
修改1:在qwt3d_enrichment_std新增3D曲线绘制类
qwt3d_enrichment_std.h
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 RGBA getColor(int pointIndex);
private:
bool smooth_;
double lineThick;
GLboolean oldstate_;
std::vector<Qwt3D::Triple> lineData;
RGBA rgba;
std::map<int,RGBA> myColorMap;
};
qwt3d_enrichment_std.cpp
Qwt3D::Line3D::Line3D()
{
rgba.a = 1;
rgba.b = 0.3;
rgba.r = 0.6;
rgba.g = 1;
}
Qwt3D::Line3D::Line3D(double thick,bool smooth)
{
lineThick = thick;
smooth_ = smooth;
rgba.a = 1;
rgba.b = 0.3;
rgba.r = 0.6;
rgba.g = 1;
}
void Qwt3D::Line3D::configure(double thick, bool smooth)
{
lineThick = thick;
smooth_ = smooth;
}
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 ++)
{
draw(lineData[i]);
}
}
void Qwt3D::Line3D::add(Qwt3D::Triple const & t)
{
lineData.push_back(t);
}
void Qwt3D::Line3D::setLineColor(RGBA color)
{
this->rgba = color;
}
修改2:在qwt3d_type.h的枚举PLOTSTYLE新增空间曲线绘制模式
enum PLOTSTYLE
{
NOPLOT , //!< No visible data
WIREFRAME , //!< Wireframe style
HIDDENLINE , //!< Hidden Line style
FILLED , //!< Color filled polygons w/o edges
FILLEDMESH , //!< Color filled polygons w/ separately colored edges
POINTS , //!< User defined style (used by Enrichments)
USER , //!< User defined style (used by Enrichments)
LINE3D_STYLE
};
修改3:在qwt3d_surfaceplot新增三维曲线绘制函数
void SurfacePlot::createLines(Line3D& p)
{
if (!actualData_p)
return;
if (p.type() != Enrichment::VERTEXENRICHMENT)
return;
p.assign(*this);
p.drawBegin();
VertexEnrichment* ve = (VertexEnrichment*)&p;
if (plotStyle() == Qwt3D::LINE3D_STYLE)
{
p.draw();
}
p.drawEnd();
}
修改4:修改数据传递的多个函数
void Plot3D::updateData(Line3D& p)
{
makeCurrent();
GLStateBewarer dt(GL_DEPTH_TEST, true);
GLStateBewarer ls(GL_LINE_SMOOTH, true);
calculateHull();
SaveGlDeleteLists(displaylists_p[DataObject], 1); // nur Daten
displaylists_p[DataObject] = glGenLists(1);
glNewList(displaylists_p[DataObject], GL_COMPILE);
/*注释掉creatEnrichments*/
// this->createEnrichments();
this->createData(p);
glEndList();
}
/*去掉了其他的模式选择*/
void SurfacePlot::createData(Line3D& p)
{
// actualData_p->datatype = Qwt3D::GRID;
// if (!actualData_p)
// return;
// if (actualData_p->datatype == Qwt3D::POLYGON)
// createDataC();
// else if (actualData_p->datatype == Qwt3D::GRID)
// {
createDataG(p);
// }
}
/*新增三维曲线绘制模式选择*/
void SurfacePlot::createDataG(Line3D& p)
{
createFloorData();
if (plotStyle() == NOPLOT)
return;
int i, j;
RGBA col;
int step = resolution();
if (plotStyle() == Qwt3D::POINTS)
{
createPoints();
return;
}
else if (plotStyle() == Qwt3D::USER)
{
if (userplotstyle_p)
createEnrichment(*userplotstyle_p);
return;
}
else if(plotStyle() == Qwt3D::LINE3D_STYLE)
{
createLines(p);
return;
}
}
对库函数做以上修改后,便可进行空间曲线的绘制了。qwtplot3d进行构建生成lib文件,具体配置方法可参考上一篇文章。
3、静态空间曲线绘制
头文件:
#ifndef Q1_H
#define Q1_H
#include "qwt3d_surfaceplot.h"
#include "qwt3d_global.h"
#include <qwt3d_parametricsurface.h>
namespace Ui {
class q1;
}
class q1 : public Qwt3D::SurfacePlot
{
public:
q1();
~q1();
void rosenbrockinit();
void addcurve();
private:
Ui::q1 *ui;
float x;
float y;
float z;
};
#endif // Q1_H
源文件:
#include "q1.h"
#include "ui_q1.h"
#include "qwt3d_function.h"
#include "line3d.h"
#include <qdebug.h>
using namespace Qwt3D;
q1::q1()
{
// ui->setupUi(this);
setPlotStyle(Qwt3D::LINE3D_STYLE);
coordinates()->setAutoScale();
setTitle("Curve3d");
setIsolines(5);
rosenbrockinit();
setShift(1,0,0);
setRotation(30,0,30);
setScale(1,1,1);
setShift(0.15,0,0);
setZoom(1);
addcurve();
}
q1::~q1()
{
// delete ui;
}
class Rosenbrock:public Function{
public:
Rosenbrock(SurfacePlot & pw):Function(pw){}
Rosenbrock(){}
double operator ()(double x,double y){
return 5*x*y;
}
};
void q1::rosenbrockinit()
{
Rosenbrock rosenbrock;
rosenbrock.setMesh(5,5);
rosenbrock.setDomain(0,100,0,100);
rosenbrock.setMinZ(0);
rosenbrock.setMaxZ(100);
rosenbrock.create(*this);
coordinates()->setGridLines(true,false,Qwt3D::LEFT|Qwt3D::BACK|Qwt3D::FLOOR);
for (unsigned i=0; i!=coordinates()->axes.size(); ++i)
{
coordinates()->axes[i].setMajors(7);
coordinates()->axes[i].setMinors(4);
}
coordinates()->axes[X1].setLabelString("x");
coordinates()->axes[Y1].setLabelString("y");
coordinates()->axes[Z1].setLabelString("z");
setCoordinateStyle(BOX);
}
void q1::addcurve()
{
Qwt3D::Line3D _l3d;
Qwt3D::Line3D *myLine1 = static_cast<Qwt3D::Line3D *>(this->addEnrichment(_l3d));
myLine1->configure(10,true);
myLine1->setLineColor(Qwt3D::RGBA(0,1,1,1));
int r;
int theta;
for(float i = 0; i < 20; i+=0.1)
{
r = i;
theta = 10+i*20;
x = r*cos(theta*3.14/180);
y = r*sin(theta*3.14/180);
z = i;
// qDebug()<<x<<","<<y<<","<<z;
myLine1->add(Qwt3D::Triple(x,y,z));
}
updateData(*myLine1);
updateGL();
}
绘制出来的空间螺旋曲线效果如下
可通过修改参数改变曲线的大小,修改公式绘制不同的曲线。也可利用计时器绘制动态曲线