Qt实现Trackball交互方式代码
来源:互联网 发布:淘宝开店培训班 编辑:程序博客网 时间:2024/05/21 21:37
毕设要用到Qt+OpenGL,生成三维模型后需要能够进行拖动旋转等用户交互,因此我实现了Trackball类型的交互代码。Trackball的原理见https://www.khronos.org/opengl/wiki/Object_Mouse_Trackball,在此只做简单介绍。
实现Trackball需要对交互时鼠标的起点和终点进行记录,根据鼠标移动的轨迹改变三维模型旋转矩阵的值,进而实现三维模型的旋转。
Trackball假设鼠标在一个三维球面上进行拖动,但是屏幕只是二维的,因此需要计算第三个维度z的坐标,计算方法很简单:
因此计算z坐标的函数如下:
float GLWidget::z(float x, float y){ const float r = 1.0; if ((x * x + y * y) <= (r * r / 2)) { return qSqrt(r * r - (x * x + y * y)); } else { return (r * r / 2 / qSqrt(x * x + y * y)); }}
为了计算方便,我们将屏幕的xy坐标都被映射到了[-1, 1]的范围之内,映射的方式在下面代码中不做解释,这样相当于屏幕上有一个半径为1的球。我们要使用鼠标移动前后的起点向量V1和终点向量V2来计算旋转轴和旋转角度,V1和V2都是单位化向量,经过单位化以后,V1和V2终点就都落在了单位球面上。那么如何计算旋转轴和旋转角度呢,公式如下:
void GLWidget::mouseMoveEvent(QMouseEvent *event){ float x1 = (float)m_lastPos.x() / (this->width() / 2) - 1.0; float y1 = 1.0 - (float)m_lastPos.y() / (this->height() / 2); float z1 = z(x1, y1); float x2 = (float)(event->x()) / (this->width() / 2) - 1.0; float y2 = 1.0 - (float)(event->y()) / (this->height() / 2); float z2 = z(x2, y2); float l1 = qSqrt(x1 * x1 + y1 * y1 + z1 * z1); float l2 = qSqrt(x2 * x2 + y2 * y2 + z2 * z2); if (event->buttons() & Qt::LeftButton) { QVector3D v1(x1 / l1, y1 / l1, z1 / l1); QVector3D v2(x2 / l2, y2 / l2, z2 / l2); QVector3D n = QVector3D::crossProduct(v1, v2); float angle = qAcos(QVector3D::dotProduct(v1, v2)); rotateBy(angle * 180 / PI, n); } m_lastPos = event->pos();}
m_lastPos类型为QPoint,记录上次事件的终点,也就是本次事件的起点。
rotateBy函数用来操作旋转矩阵,代码如下:
void GLWidget::rotateBy(float angle, QVector3D &vector){ QMatrix4x4 temp = m_rotate; m_rotate.setToIdentity(); m_rotate.rotate(angle, vector); m_rotate *= temp; update();}
m_rotate类型为QMatrix4x4,用来记录模型的旋转矩阵。这里需要注意的是,由于矩阵乘法不遵守交换律,因此需要将最后产生的旋转量放在最左侧,最后与模型点阵相乘,因此有了temp变量。
由于是毕业设计,因此其余代码就不放上来了。
- Qt实现Trackball交互方式代码
- OpenGL 交互方式Trackball的实现代码
- OpenGL+Qt界面(三) Qt中实现OPENGL的基本交互+代码
- OpenGL Object Mouse Trackball 三维物体的trackball旋转实现原理
- js动态交互实现方式
- 8 Three.js使用轨迹球插件(trackball)增加对模型的交互功能
- Trackball详解????
- WKWebView 和本地代码交互方式
- 实现js与Qt程序的交互
- QT同时实现通信、界面交互总结
- Qt和Javascript交互的两种方式
- 使用Qt Designer和手动编写代码两种方式实现多窗口切换程序(Qt基础)
- QML界面与Qt/C++代码进行数据交互
- Trackball rotate的OSG实现(一)(不是manipulator那种~是动物体那种!)
- Trackball rotate的OSG实现(二)(不是manipulator那种~是动物体那种!)
- Qt代码实现QDialog对象
- <Linux+Qt>一种移植qt可执行代码的方式
- WebView的JavaScript与本地代码三种交互方式
- poj 2503 map用法
- Framework7中Template7的使用
- 完全背包多重背包模板
- Java Web 之过滤器Filter详解
- sensor输出四种类型:YUV ,RGB ,RAW RGB ,JPEG
- Qt实现Trackball交互方式代码
- (4.6.23.2)Android之面向切面编程:Aspect集成示例之DebugTrace 与 SecurityCheckAnnotation
- Qt元系统之类型注册
- java如何将网页表格导出为excel
- PHP循环遍历数组的3种方法list()、each()和while总结
- easyui tabs 在同一个页面中打开多个tab多页面中变量名或函数名重复问题
- Deep Learning(深度学习)学习笔记整理系列之(二)
- 基于QualComm的mmc driver解析(Kernel-3.10)——(1)mmc bus
- synchronized与volatile的区别