c++ QT opengl鼠标控制平移、缩放、绕点旋转

这篇具有很好参考价值的文章主要介绍了c++ QT opengl鼠标控制平移、缩放、绕点旋转。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目的:实现鼠标控制正方形的平移、缩放、以及围绕自身某个点旋转。

要求:

  1. 坐标系固定在左下角
  2. 坐标系和正方形一起旋转,但不平移与缩放
  3. 鼠标左键平移正方形,右键旋转,滚轮缩放(放大与缩小)

步骤

  1. 编写绘制正方形与坐标系函数
  2. 在OpenGL窗口界面绘制
  3. 实现鼠标左键平移移动,右键旋转,滚轮缩放(放大与缩小)
  4. 设置正方形的旋转点,以及坐标系位置
  5. 将对应的鼠标事件应用到正方形与坐标系

实现:

  • 步骤1:编写绘制正方形与坐标系函数(比较简单,就不贴代码了)
	drawObjects();
	drawaxis();
  • 步骤2:在OpenGL窗口界面绘制
  • 步骤5:将对应的鼠标事件应用到正方形与坐标系

void paintGL();
绘制OpenGL窗口界面。在这里绘制图形,并对图形设置了不同的变换。

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    int renderMode;
    glGetIntegerv(GL_RENDER_MODE, &renderMode);

    if (renderMode != GL_SELECT) {
        // Matrix setting
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        const float aspect = static_cast<float>(width()) / height();
        gluPerspective(45.0, aspect, 1.0, 1000.0);
    }
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt(0.0, 0.0, 10.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);

    glPushMatrix();
    glMultMatrixf(m_transform.constData());//对drawObjects()的图形进行平移,旋转
    glScalef(zscale,zscale,zscale);//缩放
    drawObjects();
    glPopMatrix();

    glPushMatrix();
    glTranslatef(-4, -3, 0);
    glMultMatrixf(axis_transform.constData());//对drawaxis()的图形进行旋转
    drawaxis();
    glPopMatrix();
  • 步骤3:设置鼠标左键平移移动,右键旋转

mouseMoveEvent(QMouseEvent* ev);

    int dx = ev->x() - m_lastPos.x();
    int dy = ev->y() - m_lastPos.y();

    if(ev->buttons() & Qt::LeftButton)
    {
        translate(dx, dy);
    }
    else if(ev->buttons() & Qt::RightButton)
    {
        objects_rotate(dx, dy);
        axis_rotate(dx, dy);
    }
    m_lastPos = ev->pos();
    update();
  • 步骤3:正方形的平移移动
    translate(int dx, int dy);
	m_translation.setX(m_translation.x() + dx * 0.01);
    m_translation.setY(m_translation.y() - dy * 0.01);
    m_transform.setToIdentity();                       //将变换矩阵重置为单位矩阵
    m_transform.translate(m_translation);              //平移到正确的位置
    m_transform.rotate(QQuaternion::fromAxisAndAngle(1, 0, 0, m_rotation.x()/* + 1*/));//将旋转状态应用到平移中
    m_transform.rotate(QQuaternion::fromAxisAndAngle(0, 1, 0, m_rotation.y()/* + 1*/));
  • 步骤3:坐标系的旋转
    axis_rotate(int dx, int dy);
// 四元数: new_rotation = q * m_rotation * q逆          // q = xRot * yRot * zRot, 即 rotate()的参数
    axis_rotation.setX(axis_rotation.x() - dy);
    axis_rotation.setY(axis_rotation.y() - dx);
    QQuaternion xRot = QQuaternion::fromAxisAndAngle(1, 0, 0, axis_rotation.x());//绕(0,0,0)点与(1,0,0)点连线,即x轴,旋转角度m_rotation.x()
    QQuaternion yRot = QQuaternion::fromAxisAndAngle(0, 1, 0, axis_rotation.y());

    axis_transform.setToIdentity();
    axis_transform.rotate(xRot * yRot);
  • 步骤3:正方形的旋转
    objects_rotate(int dx, int dy);
	m_rotation.setX(m_rotation.x() - dy);
    m_rotation.setY(m_rotation.y() - dx);
    QQuaternion xRot = QQuaternion::fromAxisAndAngle(1, 0, 0, m_rotation.x());//绕(0,0,0)点与(1,0,0)点连线,即x轴,旋转角度m_rotation.x()
    QQuaternion yRot = QQuaternion::fromAxisAndAngle(0, 1, 0, m_rotation.y());
    m_transform.setToIdentity();
    m_transform.translate(m_translation); //将平移状态应用到旋转
    m_transform.rotate(xRot * yRot);//四元数相乘,表示两次旋转
  • 步骤3:正方形的滚轮缩放(放大与缩小)
    wheelEvent(QWheelEvent *ev);
	int delta = ev->delta();  // positive when wheel up, delta +/- 120 when wheel +/- 1
    if(zscale-delta*2.0*1e-3>0)
        zscale += delta*2.0*1e-3;
    update();
  • 步骤4:设置正方形的旋转点,以及坐标系位置
    qt opengl中想要绕着某个点旋转,主要思维是将图形平移到该点位置,进行旋转操作后,再对图形做逆平移
    //*******设置坐标轴的旋转中心********
    float centre_x, centre_y;
    centre_x = -4;
    centre_y = -3;
    axis_translation.setX(centre_x);
    axis_translation.setY(centre_y);
    //******设置坐标轴的旋转中心*********
    axis_transform.translate(axis_translation);//平移到centre点的位置
    
    axis_transform.rotate(xRot * yRot);//旋转
    
    axis_translation.setX(-centre_x);
    axis_translation.setY(-centre_y);
    axis_transform.translate(axis_translation);//逆平移

在最近研究这个问题的过程中,发现如果同时对图形做了平移与旋转,用上述方法难点在于对于旋转点的世界坐标的获取。目前只学习了将屏幕坐标转换为世界坐标,但是对于追踪某一点的世界坐标还有待学习(有懂的大佬希望可以教教我qwq)。然而眼前的问题还是要尽快解决的,后来发现了下面的方法。

	glTranslatef(1, 1, 0);

没错,就是平移!其实也就是将正方形想要围绕旋转的点平移到原点(0,0)的位置。
我的正方形边长为2,所以这个代码意思是将正方形向右上方平移(二维平面),结果就是正方形左下角到了原点的位置。也就是我的正方形设置是围绕左下角旋转,在一系列平移,缩放后,可以一直围绕左下角旋转。

效果展示

opengl鼠标旋转,c++,qt
opengl鼠标旋转,c++,qt文章来源地址https://www.toymoban.com/news/detail-740778.html

题外话

  1. 对于上图坐标系显示文字的绘制办法下次记录
  2. 鼠标点击,选择拾取glSelectBuffer整理之后再记录

到了这里,关于c++ QT opengl鼠标控制平移、缩放、绕点旋转的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • qt QPainter 实现图片的缩放和平移

    头文件 CPP lable 不是必要的,设置好关键的2个值最重要

    2024年02月16日
    浏览(35)
  • 【C++】【Opencv】cv::warpAffine()仿射变换函数详解,实现平移、缩放和旋转等功能

    仿射变换是一种二维变换,它可以将一个二维图形映射到另一个二维图形上,保持了图形的“形状”和“大小”不变,但可能会改变图形的方向和位置。仿射变换可以用一个线性变换矩阵来表示,该矩阵包含了六个参数,可以进行平移、缩放、旋转等操作。通过原理、函数和

    2024年02月05日
    浏览(56)
  • Unity鼠标控制3D物体的移动、旋转、缩放

    1.使用协程 2.鼠标左键控制物体移动,鼠标碰到物体,物体颜色改变 1. 控制物体左右旋转,上下旋转 2. 控制摄像机以物体为中心旋转 脚本挂载到摄像机上 1. 基于物体本身的Transform的缩放 2. 基于摄像机的远近的缩放 脚本挂载到摄像机上

    2024年02月11日
    浏览(50)
  • Unity 通过键盘鼠标控制物体移动、旋转、缩放的方法

    在Unity中,使用键盘ADWS键控制物体移动,通过鼠标左键控制物体旋转,鼠标中键控制物体缩放是再常见不过的方法。 方法如下:  效果如下:Unity 通过键盘鼠标控制物体移动、旋转、缩放_哔哩哔哩_bilibili

    2024年02月03日
    浏览(46)
  • GLSL——旋转、平移和缩放

    hello 兄弟们,好久不见撒,我又回来啦!,今天主要讲解如何在顶点着色器中进行旋转、平移和缩放,涉及到矩阵和向量方面的知识哦,忘记的可以翻一下高中数学啦,在讲之前,先回顾一下矩阵和向量点积的知识,矩阵点乘向量,等于矩阵的每一行分别和向量相乘的和,如

    2024年02月16日
    浏览(40)
  • Matlab图像的平移,旋转,缩放,裁剪

    %%------------------------Matlab图像的平移,旋转,缩放,裁剪------------------------------- %-------------------头文件----------------------------- clc ; %清屏幕 clear ; %删除所有的变量 close all ; %将所有打开的图片关掉 %--------------------图像平移 imtranslate-------------------------- A = imread(\\\'1.jpg\\\') ; subplot(

    2024年02月04日
    浏览(42)
  • 【OpenCV】图像变换(缩放、平移、旋转、仿射)

    图像变换是指通过对图像进行缩放、平移、旋转、仿射、透视等变换来改变图像的形状和大小。在本篇博客中,我们将详细介绍OpenCV中的图像变换函数,并提供示例代码以帮助读者更好地理解这些函数的使用方法。 缩放变换是指通过改变图像的大小来改变图像的形状。在Op

    2024年02月07日
    浏览(57)
  • cesium 3DTileset的平移、旋转、缩放

    加载模型 平移和修改高度 方法一:

    2024年02月12日
    浏览(38)
  • webgl-矩阵、旋转、平移、缩放 glMatrix组件

    引入新组建glMatrix glMatrix.js /*! @fileoverview gl-matrix - High performance matrix and vector operations @author Brandon Jones @author Colin MacKenzie IV @version 3.4.3 Copyright (c) 2015-2021, Brandon Jones, Colin MacKenzie IV. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation f

    2024年02月10日
    浏览(45)
  • 二维坐标基本变换(平移、旋转、缩放、镜像、阵列)

    诸如图像、模型等的基本变换,实际上都是点坐标的变换,通过矩阵,可以非常方便的达到这个目的。在下文仅介绍二维坐标变换原理。 首先,定义点类如下: 注意,为了形式统一,变换矩阵应统一为3*3阶,同理,对于三维坐标变换矩阵应是4*4阶。关于矩阵的表示,实际上

    2024年02月04日
    浏览(76)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包