当前位置: 首页 > news >正文

QT三维图形4

我们先把基本的功能写上:

#include <QGroupBox>
#include "qDoubleSlider.hpp"
#include <qlabel.h>
#include <qgridlayout.h>
class My3DCentralPoint : public QGroupBox {
	Q_OBJECT

public:
	My3DCentralPoint(QWidget * parent = Q_NULLPTR);
	~My3DCentralPoint();

	QDoubleSlider *xSlider4Pos;
	QDoubleSlider *ySlider4Pos;
	QDoubleSlider *zSlider4Pos;
	QLabel *xLabelPos;
	QLabel *yLabelPos;
	QLabel *zLabelPos;

	double xLeft, xRight;
	double yLeft, yRight;
	double zLeft, zRight;
	double xCurrent, yCurrent, zCurrent;

signals:
	void needUpdate(void);

private slots:
	void xBoundaryChanged(double);
	void yBoundaryChanged(double);
	void zBoundaryChanged(double);

	void xPosChanged(double);
	void yPosChanged(double);
	void zPosChanged(double);
};

里面的xLeft这些分别是中心点在各个方向上可以运动的左右边界。

信号是发送给之前的OpenGL类的,用于其更新显示区。

槽里面有自身使用的三个槽:

    void xPosChanged(double);
    void yPosChanged(double);
    void zPosChanged(double);

当该类里面的滑动条运动的时候,要通知我们的类去修改坐标值:

void My3DCentralPoint::xPosChanged(double Value) {
	xCurrent = Value;
	centralRectPos[0] = xCurrent;
	emit needUpdate();
}
void My3DCentralPoint::yPosChanged(double Value) {
	yCurrent = Value;
	centralRectPos[1] = yCurrent;
	emit needUpdate();
}
void My3DCentralPoint::zPosChanged(double Value) {
	emit needUpdate();
	centralRectPos[2] = zCurrent;
	zCurrent = Value;
}

而剩下的三个槽,则比较复杂,我们待会再说。

#include "my3dcentralpoint.hpp"
#include <qopenglwindow.h>
extern GLfloat centralRectPos[3];
extern GLfloat halfBoundaries[3];

My3DCentralPoint::My3DCentralPoint(QWidget * parent) : QGroupBox(parent) {
	setTitle("Central Point Setting");
	QGridLayout *gridlayout = new QGridLayout(this);
	xSlider4Pos = new QDoubleSlider;
	ySlider4Pos = new QDoubleSlider;
	zSlider4Pos = new QDoubleSlider;
	xLabelPos = new QLabel("xPos: ");
	yLabelPos = new QLabel("yPos: ");
	zLabelPos = new QLabel("zPos: ");
	gridlayout->addWidget(xLabelPos, 0, 0);
	gridlayout->addWidget(yLabelPos, 1, 0);
	gridlayout->addWidget(zLabelPos, 2, 0);
	gridlayout->addWidget(xSlider4Pos, 0, 1);
	gridlayout->addWidget(ySlider4Pos, 1, 1);
	gridlayout->addWidget(zSlider4Pos, 2, 1);


	xLeft = halfBoundaries[0] - 0.5;
	xRight =  0.5 - halfBoundaries[0];
	yLeft = halfBoundaries[1] - 0.5;
	yRight = 0.5 - halfBoundaries[1];
	zLeft = halfBoundaries[2] - 0.5;
	zRight = 0.5 - halfBoundaries[2];
	xCurrent = centralRectPos[0];
	yCurrent = centralRectPos[1];
	zCurrent = centralRectPos[2];
	xSlider4Pos->setRange(xLeft, xRight);
	xSlider4Pos->setValue(centralRectPos[0]);
	xSlider4Pos->setRange(yLeft, yRight);
	xSlider4Pos->setValue(centralRectPos[1]);
	xSlider4Pos->setRange(zLeft, zRight);
	xSlider4Pos->setValue(centralRectPos[2]);

	connect(xSlider4Pos, SIGNAL(valueChanged(double)),
		this, SLOT(xPosChanged(double)));
	connect(ySlider4Pos, SIGNAL(valueChanged(double)),
		this, SLOT(yPosChanged(double)));
	connect(zSlider4Pos, SIGNAL(valueChanged(double)),
		this, SLOT(zPosChanged(double)));


}

在构造函数中,我们首先根据初始值来把滑动条的范围给限定好。然后绑定自己的信号和槽。

在DockWidget中,我们再绑定另外三个槽,以及我们这个类中的信号:

connect(my3dhalfboundary->xSlider4HalfBnd, SIGNAL(valueChanged(double)),
		my3dcentralpoint, SLOT(xBoundaryChanged(double)));
	connect(my3dhalfboundary->ySlider4HalfBnd, SIGNAL(valueChanged(double)),
		my3dcentralpoint, SLOT(yBoundaryChanged(double)));
	connect(my3dhalfboundary->zSlider4HalfBnd, SIGNAL(valueChanged(double)),
		my3dcentralpoint, SLOT(zBoundaryChanged(double)));

	connect(my3dcentralpoint, SIGNAL(needUpdate(void)),
		my3dDisplayWidget, SLOT(neededUpdate(void)));

这样相当于边界变化以后,中心点位置类先做调整,把数组更新,然后告诉OpenGL部件需要重新更新一下。

之后再单独拿出来一个轴的槽来讲解:

void My3DCentralPoint::xBoundaryChanged(double Value) {
	if ((xCurrent - Value) < -0.5) {
		xCurrent =  Value - 0.5;
		
	}
	else if ((xCurrent + Value)>0.5) {
		xCurrent = 0.5 - Value;
	}
	centralRectPos[0] = xCurrent;
	halfBoundaries[0] = Value;
	xSlider4Pos->setRange(Value - 0.5, 0.5 - Value);
	emit needUpdate();
}

如果当前中心点位置的值(xCurrent)减去边界值(Value)超过了边界,则我们需要移动中心点,让它往中间移(即令立方体的边贴着大立方体的边)。然后给中心点设置其变化范围。

也就是说,假如我们现在的边界长是0.3了,我们的坐标位置在0.3处,而0.3+0.3是大于0.5的,所以中心点是需要往中间来偏移。

现在各个功能都已经说完了,我们看一下最后的效果:

相关文章:

  • icache的方面以及使用
  • cmp bne 以及sub指令的详解
  • 关于ARM Cortex a 系列的看门狗定时器
  • C语言之 认识可变参数
  • ARM cortex a 的SDRAM (DDR)
  • C语言 之递归函数
  • C语言 之建立静态链接库
  • ARM的PWM定时器1
  • RTC闹钟的中断处理方法以及程序设计
  • altium designer 制作元器件封装库
  • VTK的Mapper
  • VTK交互系统 1 交互模式入门
  • VTK显示像素图
  • VTK交互系统 2 交互器样式
  • VTK交互系统 3 自定义交互器样式
  • [微信小程序] 使用ES6特性Class后出现编译异常
  • 4. 路由到控制器 - Laravel从零开始教程
  • Gradle 5.0 正式版发布
  • GraphQL学习过程应该是这样的
  • UMLCHINA 首席专家潘加宇鼎力推荐
  • Vue学习第二天
  • 关于List、List?、ListObject的区别
  • 盘点那些不知名却常用的 Git 操作
  • 如何正确配置 Ubuntu 14.04 服务器?
  • 适配iPhoneX、iPhoneXs、iPhoneXs Max、iPhoneXr 屏幕尺寸及安全区域
  • ​configparser --- 配置文件解析器​
  • ​力扣解法汇总1802. 有界数组中指定下标处的最大值
  • #Linux(权限管理)
  • (delphi11最新学习资料) Object Pascal 学习笔记---第5章第5节(delphi中的指针)
  • (MonoGame从入门到放弃-1) MonoGame环境搭建
  • (六)c52学习之旅-独立按键
  • .axf 转化 .bin文件 的方法
  • .NET 4.0中使用内存映射文件实现进程通讯
  • .NET 8 中引入新的 IHostedLifecycleService 接口 实现定时任务
  • .net core webapi Startup 注入ConfigurePrimaryHttpMessageHandler
  • .NET Core 通过 Ef Core 操作 Mysql
  • .NET Core/Framework 创建委托以大幅度提高反射调用的性能
  • .NET Framework 服务实现监控可观测性最佳实践
  • .net Signalr 使用笔记
  • .NET 实现 NTFS 文件系统的硬链接 mklink /J(Junction)
  • .NET项目中存在多个web.config文件时的加载顺序
  • .net专家(张羿专栏)
  • ;号自动换行
  • []FET-430SIM508 研究日志 11.3.31
  • [C++]拼图游戏
  • [CLickhouse] 学习小计
  • [CTF]php is_numeric绕过
  • [Docker]十一.Docker Swarm集群raft算法,Docker Swarm Web管理工具
  • [echarts] y轴不显示0
  • [IM] [Webhook] Webhook实现IM平台机器人
  • [javascript]Tab menu实现
  • [Java并发编程实战] 共享对象之可见性
  • [LeetBook]【学习日记】获取子字符串 + 颠倒子字符串顺序
  • [leetcode 双指针]
  • [leetcode] 四数之和 M