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

景区旅游网站平台建设方案销售案例网站

景区旅游网站平台建设方案,销售案例网站,立邦刷新服务多少钱一平米,wordpress合并js文章目录鼠标控制沿着指定轴旋转方案一:根据两次鼠标坐标来得出旋转方向、角度步骤问题方案二:结合arkball算法实现用户友好旋转(推荐)步骤缺点鼠标控制沿着指定轴旋转 有这么一个开发场景,选定指定轴,操作…

文章目录

  • 鼠标控制沿着指定轴旋转
    • 方案一:根据两次鼠标坐标来得出旋转方向、角度
      • 步骤
      • 问题
    • 方案二:结合arkball算法实现用户友好旋转(推荐)
      • 步骤
      • 缺点

鼠标控制沿着指定轴旋转

有这么一个开发场景,选定指定轴,操作鼠标控制模型绕着着指定轴旋转。

代码仅供参考,可根据实际应用场景进行调整。

方案一:根据两次鼠标坐标来得出旋转方向、角度

void CCabinet3DScene::rotateByAxis(int axis, QMouseEvent *event)
{QVector3D offset = getMouseMoveOffset(event);m_lastPos = event->pos();SPoint3D sRotate = m_pData->GetRotate();QVector3D delta = QVector3D(sRotate.x, sRotate.y, sRotate.z);float rotate = 0.0f;bool bMove = true;// 根据axis参数约束移动旋转switch(axis){case enX:{if (offset.x() >= 0){rotate = (delta.x() + 1 > 360) ? (delta.x() + 1 - 360) : (delta.x() + 1);delta.setX(rotate);}else{rotate = (delta.x() - 1 < -360) ? (delta.x() - 1 + 360) : (delta.x() - 1);delta.setX(rotate);}}break;case enY:{if (offset.y() >= 0){rotate = (delta.y() + 1 > 360) ? (delta.y() + 1 - 360) : (delta.y() + 1);delta.setY(rotate);}else{rotate = (delta.y() - 1 < -360) ? (delta.y() - 1 + 360) : (delta.y() - 1);delta.setY(rotate);}}break;case enZ:{if (offset.z() >= 0){rotate = (delta.z() + 1 > 360) ? (delta.z() + 1 - 360) : (delta.z() + 1);delta.setZ(rotate);}else{rotate = (delta.z() - 1 < -360) ? (delta.z() - 1 + 360) : (delta.z() - 1);delta.setZ(rotate);}}break;default :bMove = false;break;}if (!bMove)return;if (m_screens.contains(m_curID))m_screens[m_curID]->setRotate(delta, true);update();
}QVector3D CCabinet3DScene::getMouseMoveOffset(QMouseEvent *event)
{makeCurrent();GLint viewport[4];GLdouble modelview[16], projection[16];glGetIntegerv(GL_VIEWPORT, viewport);glGetDoublev(GL_MODELVIEW_MATRIX, modelview);glGetDoublev(GL_PROJECTION_MATRIX, projection);float lastZ = 0.0f;int lastWinX = m_lastPos.x();int lastWinY = viewport[3] - m_lastPos.y();glReadPixels(lastWinX, lastWinY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &lastZ);double lastWorldX, lastWorldY, lastWorldZ;gluUnProject(lastWinX, lastWinY, lastZ, modelview, projection, viewport, &lastWorldX, &lastWorldY, &lastWorldZ);float currZ = 0.0f;int currWinX = event->pos().x();int currWinY = viewport[3] - event->pos().y();glReadPixels(currWinX, currWinY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &currZ);double currWorldX, currWorldY, currWorldZ;gluUnProject(currWinX, currWinY, currZ, modelview, projection, viewport, &currWorldX, &currWorldY, &currWorldZ);QVector3D delta = QVector3D(currWorldX - lastWorldX, currWorldY - lastWorldY, currWorldZ - lastWorldZ);doneCurrent();return delta * devicePixelRatioF();
}

步骤

  • 根据鼠标curPos和lastPos世界坐标的差值计算delta;
  • 根据选定的旋转轴,取出delta对应的分量;
  • 根据其值设置旋转方向,固定旋转为1。

问题

  • 用户体验不友好:只根据一个目标分量判断方向,当用户操作鼠标在其他分量上变化大时,呈现的效果不好…
  • 鼠标做画圈操作,会出现模型来回摆动的现象。
  • 逆时针、顺时针操作呈现的效果不是相反的。

方案二:结合arkball算法实现用户友好旋转(推荐)

void CCabinet3DScene::rotateByAxis(int axis, QMouseEvent *event)
{QVector3D va = mapToArcball(m_lastPos);QVector3D vb = mapToArcball(event->pos());// 计算方向和角度float angle = acos(qBound(-1.0f, QVector3D::dotProduct(va, vb), 1.0f));float cross = va.x() * vb.y() - va.y() * vb.x();float sign = cross >= 0 ? -1.0f : 1.0f;float constrainedAngle = sign * angle * 180.0f / M_PI; ; // 转为角度m_lastPos = event->pos();SPoint3D sRotate = m_pData->GetRotate();QVector3D delta = QVector3D(sRotate.x, sRotate.y, sRotate.z);float rotate = 0.0f;bool bMove = true;// 根据axis参数约束移动旋转switch(axis){case enX:{rotate = delta.x() + constrainedAngle;if(rotate >= 360 || rotate <= -360)rotate = 0;delta.setX(rotate);}break;case enY:{rotate = delta.y() + constrainedAngle;if(rotate >= 360 || rotate <= -360)rotate = 0;delta.setY(rotate);}break;case enZ:{rotate = delta.z() + constrainedAngle;if(rotate >= 360 || rotate <= -360)rotate = 0;delta.setZ(rotate);}break;default :bMove = false;break;}if (!bMove)return;if (m_screens.contains(m_curID))m_screens[m_curID]->setRotate(delta, true);update();
}QVector3D CCabinet3DScene::mapToArcball(QPointF pos)
{float x = (2.0f * pos.x() - width()) / width();float y = (height() - 2.0f * pos.y()) / height(); // y反转float z2 = 1.0f - x * x - y * y;float z = z2 > 0.0f ? sqrt(z2) : 0.0f;return QVector3D(x, y, z).normalized();
}

步骤

  • 计算鼠标位置映射到球体的向量va、vb;
  • 根据两个向量计算出旋转角度,也可以为固定值;
  • 根据向量前两个维度计算旋转方向。

缺点

  • 依赖中心点的选取,这里直接选取屏幕中心,如果鼠标画圈没有包含中心点的话,也会出现用户不友好的现象;
http://www.dtcms.com/a/528943.html

相关文章:

  • 【小白笔记】input() 和 print() 这两个函数
  • 营销型网站哪家做的好东莞app
  • 部署PHP8.4(KylinV10SP3、Ubuntu2204、Rocky9.3)
  • 一套配置 双重体验:孪易 IOC 化解 端/流双渲染应用难题
  • jQuery Mobile 实例
  • 免费行情软件网站mnw做教育网站
  • WordPress网站hym地图凯里做网站
  • 东莞做网站优化哪家好网站识别手机电脑代码
  • Java---String类
  • Flame 中使用 GameWidget(完整使用手册)
  • html5制作手机网站做淘宝代码的网站
  • P2216 [HAOI2007] 理想的正方形
  • 设计模式23种-C++实现
  • 涌现的架构:集体智能框架构建解析
  • 大模型技术的核心之“效率高”
  • 分类网站怎么做seo什么网站出项目找人做
  • Unity 3D笔记(进阶部分)——《B站阿发你好》
  • 怎样建设好网站如何评判一个网站建设的怎么样
  • 【017】旅游网
  • 两款实用电脑工具:屏幕监控与文件整理,提升工作效率
  • 用php做的网站有写软文怎么接单子
  • temu跨境电商厦门seo俱乐部
  • unity实现2D人物从上面踩踏敌人,敌人减血的简易方法(类似马里奥的攻击手段)
  • Spring AI 1.0 核心功能脉络
  • 【清除 Mac DNS 缓存】Mac 电脑能访问外网却无法加载特定页面?你的 DNS 缓存“发霉”了!
  • 局域网手机/平板无数据线传输文件-通过网络传输LocalSend
  • 网站开发时ie11的兼容网站开发的prd 怎么写
  • 电分:无功、有功,功率因数
  • Spring Bean作用域全解析
  • 网页制作与网站建设wordpress插件库