Qt+OpenGL绘制三维坐标系(动态曲线显示)

7 篇文章 0 订阅

*Qt使用OpenGL绘制三维曲线时,需要加入OPenGL模块。
此处的绘制的核心代码同样可以移植到MFC上显示。
如下代码可以再进行优化。

#ifndef QTDRAW3DCTRL_H
#define QTDRAW3DCTRL_H
#include <QtOpenGL/qgl.h>
#include <QWidget>
#include <QGridLayout>
#include <QtGui/QtGui>
#include <QtOpenGL/QtOpenGL>
#include <QtOpenGL/QGLWidget>
#include <QtWidgets/QOpenGLWidget>
#include <QtOpenGL/QGL>
#include <vector>

#include <GL/glu.h>
#include "ui_qtdraw3dctrl.h"

#ifdef _DEBUG
#pragma comment(lib, "Qt5OpenGLd")
#else
#pragma comment(lib, "Qt5OpenGL")
#endif
#ifdef _DEBUG
#include <QDebug>
#endif
class QtDraw3DCtrl : public QGLWidget
{
	Q_OBJECT

public:
	QtDraw3DCtrl(QWidget *parent = 0);
	~QtDraw3DCtrl();
	void GLGrid(float pt1x, float pt1y, float pt1z, float pt2x, float pt2y, float pt2z, int num);
protected:
	int m_scloe;
	double m_rotx;
	double m_roty;
	double m_rotz;
	QPoint m_rotPosOld;
	int m_base;
	int m_isize;
	double m_count;

	double m_valuex;
	double m_valuey;
	double m_valuez;
	std::vector<double> m_vetorx;
	std::vector<double> m_vetory;
	std::vector<double> m_vetorz;

public slots:
	void UpdateSlots();
	
protected:
	virtual void initializeGL();
	virtual void resizeGL(int w, int h);
	virtual void paintGL();
	virtual void mousePressEvent(QMouseEvent *event);
	virtual void mouseMoveEvent(QMouseEvent *event);
	virtual void wheelEvent(QWheelEvent *event);
private:
	Ui::QtDraw3DCtrl ui;
};

#endif // QTDRAW3DCTRL_H

#include "qtdraw3dctrl.h"

QtDraw3DCtrl::QtDraw3DCtrl(QWidget *parent)
	: QGLWidget(parent)
{
	ui.setupUi(this);
	m_scloe = -15;
	m_rotx = 0;
	m_roty = 0;
	m_rotz = 0;
	m_count = -40;
	m_isize = 4;
	QTimer* timer = new QTimer(this);
	timer->setInterval(10);
	connect(timer, SIGNAL(timeout()), this, SLOT(UpdateSlots()));
	timer->start();
}

QtDraw3DCtrl::~QtDraw3DCtrl()
{
}

void QtDraw3DCtrl::UpdateSlots()
{
	m_valuex = m_count*0.1;
	m_valuey = sin(m_count)*0.1;
	m_valuez = cos(m_count)*0.1;
	m_count+= 0.05;

	update();
}

void QtDraw3DCtrl::initializeGL()
{
	glClearColor(0.0, 0.2, 0.3, 1.0);
	glShadeModel(GL_SMOOTH);
	glEnable(GL_DEPTH);
}

void QtDraw3DCtrl::resizeGL(int w, int h)
{
	if (h == 0)//防止height为0
	{
		h = 1;
	}
	glViewport(0, 0,(GLint)w, (GLint)h);//重置当前的视口

	glMatrixMode(GL_PROJECTION);//选择投影矩阵
	glLoadIdentity();//重置投影矩阵
	gluPerspective(45.0, (GLfloat)w / (GLfloat)h, 0.001, 1000.0);//建立透视投影矩阵

	glMatrixMode(GL_MODELVIEW);//选择模型观察矩阵
	glLoadIdentity();//重置模型观察矩阵
	
}
void QtDraw3DCtrl::paintGL()
{

	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);//清除屏幕和深度缓存
	glLoadIdentity();//重置当前的模型观察矩阵。在glLoadIdentity()调用之后,函数返回之前,添加代码来创建基本的形
					 //目前所做的就是将屏幕清除成前面所决定的颜色,清除深度缓存并且重置场景,仍然没绘制任何东西。
					 //glPolygonMode(GL_FRONT_AND_BACK ,GL_LINE );//前后面,填充方式(点point、线line、FILL)

	//旋转显示窗口
	glTranslatef(0, 0, m_scloe);
	glRotatef(fabs(m_roty), m_rotx, m_roty, m_rotz);
	GLUquadricObj *objCylinder = gluNewQuadric();

	int pt = 8;
	int num = 40;
	//网格
	//X
	glPushMatrix();
	glColor3f(0.8, 0.8, 0.8);
	glTranslatef(-m_isize, -m_isize, -m_isize);
	GLGrid(0, 0, 0, pt, 0, pt, num);
	glPopMatrix();

	glPushMatrix();
	glColor3f(1, 0, 0);
	glTranslatef(m_isize, -m_isize, -m_isize);
	glRotatef(90, 0, 1, 0.0);
	gluCylinder(objCylinder, 0.1, 0.0, 0.2, 100, 1);                 
	glPopMatrix();

	//Y
	glPushMatrix();
	glTranslated(-m_isize, m_isize, -m_isize);
	glRotatef(90, 1.0, 0.0, 0.0);
	glColor3f(0.8, 0.8, 0.8);
	GLGrid(0, 0, 0, pt, 0, pt, num);
	glPopMatrix();

	glPushMatrix();
	glColor3f(0, 1, 0);
	glTranslatef(-m_isize, m_isize, -m_isize);
	glRotatef(-90, 1, 0, 0);
	gluCylinder(objCylinder, 0.1, 0.0, 0.2, 100, 1);                 	
	glPopMatrix();

	//Z
	glPushMatrix();
	glTranslatef(-m_isize, -m_isize, -m_isize);
	glRotatef(90, 0.0, 0.0, 1.0);
	glColor3f(0.8, 0.8, 0.8);
	GLGrid(0, 0, 0, pt, 0, pt, num);
	glPopMatrix();

	glPushMatrix();
	glColor3f(0, 1, 1);
	glTranslatef(-m_isize, -m_isize, m_isize);
	glRotatef(90, 0, 0, 1);
	gluCylinder(objCylinder, 0.1, 0.0, 0.2, 100, 1);                
	glPopMatrix();

	if (m_vetorx.size() >= 2) {
		glBegin(GL_LINE_STRIP);
		glTranslatef(-m_isize, -m_isize, -m_isize);
		glColor3f(1, 0, 1);
		for (int i = 0; i < m_vetorx.size(); i++) {
			glVertex3f(m_vetorx[i], m_vetory[i], m_vetorz[i]);
		}

		glEnd();
		glFlush();
	}

	if (m_vetorx.size() >= 2) {
		glBegin(GL_LINE_STRIP);
		glTranslatef(-m_isize, m_isize, -m_isize);
		glColor3f(1, 0, 0);
		for (int i = 0; i < m_vetorx.size(); i++) {
			//glVertex3f(m_vetory[i], m_vetorx[i], m_vetorz[i]);
			glVertex3f(m_vetorx[i], 3*m_vetory[i], 3*m_vetorz[i]);
		}

		glEnd();
		glFlush();
	}

	if (m_vetorx.size() >= 2) {
		glBegin(GL_LINE_STRIP);
		glTranslatef(-m_isize, m_isize, -m_isize);
		glColor3f(1, 1, 0);
		for (int i = 0; i < m_vetorx.size(); i++) {
			glVertex3f(m_vetorz[i], m_vetory[i], m_vetorx[i]);
		}

		glEnd();
		glFlush();
	}

	m_vetorx.push_back(m_valuex);
	m_vetory.push_back(m_valuey);
	m_vetorz.push_back(m_valuez);
}

void QtDraw3DCtrl::mousePressEvent(QMouseEvent *event)
{
	QPoint pos = event->pos();
	qDebug() << "x: " << pos.x() << "  y:" << pos.y();
}

void QtDraw3DCtrl::mouseMoveEvent(QMouseEvent *event)
{
	QPoint pos = event->pos();
	qDebug() << "x: " << pos.x() << "  y:" << pos.y();

	if (pos.y()  > m_rotPosOld.y())
	{
		m_rotz -= 1;
		qDebug() << m_rotz;

		m_rotx -= 1;
		qDebug() << m_rotx;

		m_roty -= 1;
		qDebug() << m_roty;
	}
	else if(pos.y()  < m_rotPosOld.y())
	{
		m_rotz += 1;
		qDebug() << m_rotz;

		m_rotx += 1;
		qDebug() << m_rotx;

		m_roty += 1;
		qDebug() << m_roty;
	} 
	m_rotPosOld = pos;

	update();
}

void QtDraw3DCtrl::wheelEvent(QWheelEvent *event)
{
	qDebug() << event->delta();

	if (event->delta() < 0) {
		m_scloe++;

	} else if (event->delta() > 0) {
		m_scloe--;
	}

	update();
}

void QtDraw3DCtrl::GLGrid(float pt1x, float pt1y, float pt1z, float pt2x, float pt2y, float pt2z, int num)

{
	const float _xLen = (pt2x - pt1x) / num;
	const float _yLen = (pt2y - pt1y) / num;
	const float _zLen = (pt2z - pt1z) / num;
	glLineWidth(0.1f);
	//glLineStipple(1, 0x0303);//线条样式

	glBegin(GL_LINES);
	glEnable(GL_LINE_SMOOTH);

	int xi = 0;
	int yi = 0;
	int zi = 0;

	//绘制平行于X的直线
	for (zi = 0; zi <= num; zi++) {
		float z = _zLen * zi + pt1z;
		for (yi = 0; yi <= num; yi++) {
			float y = _yLen * yi + pt1y;
			glVertex3f(pt1x, y, z);
			glVertex3f(pt2x, y, z);
			
		}
	}
	绘制平行于Y的直线
	for (zi = 0; zi <= num; zi++) {
		float z = _zLen * zi + pt1z;
		for (xi = 0; xi <= num; xi++) {
			float x = _xLen * xi + pt1x;
			glVertex3f(x, pt1y, z);
			glVertex3f(x, pt2y, z);
		}
	}
	//绘制平行于Z的直线
	for (yi = 0; yi <= num; yi++) {
		float y = _yLen * yi + pt1y;
		for (xi = 0; xi <= num; xi++) {
			float x = _xLen * xi + pt1x;
			glVertex3f(x, y, pt1z);
			glVertex3f(x, y, pt2z);
		}
	}
	glEnd();
}

在这里插入图片描述

  • 14
    点赞
  • 174
    收藏
    觉得还不错? 一键收藏
  • 15
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值