博客
关于我
分享 HT 实用技巧:实现指南针和 3D 魔方导航
阅读量:464 次
发布时间:2019-03-06

本文共 3376 字,大约阅读时间需要 11 分钟。

三维场景中常需要一个方位标识,用以确定场景所处的方向。常见的表现形式包括指南针和方位魔方。参考百度百科中的maya界面,可以看到右上角有一个标识方位的小盒子,这就是方位指示工具。

Hightopo的HT for Web产品能够方便地构建轻量化的3D可视化场景。在web端,我们可以利用HT 2D引擎和3D渲染引擎来实现这个功能,搭建一个简易的maya操作界面。预览地址已移除。

在这个界面中,我们使用了一个二维场景和两个三维场景,具体效果如下:

页面布局如下:指南针通过在ht.graph.GraphView中设置一个事先绘制好的图标来实现,只需将它放置在图纸的左上角即可。方位魔方通过在一个小场景(ht.graph3d.Graph3dView)中放置魔方模型来实现,然后将这个小场景放置在图纸的右上角即可。主三维场景作为背景放置在整个二维页面的下方。

代码示例如下:

const g3d = new ht.graph3d.Graph3dView();g3d.setOriginAxisVisible(true);g3d.setGridVisible(true);g3d.addToDOM();const g2d = new ht.graph.GraphView();g2d.deserialize('displays/test.json', json => {    g2d.addToDOM(g3d.getView());});

位置关系:Z轴负半轴为北方,Z轴正半轴为南方,X轴正半轴为东方,X轴负半轴为西方。

指南针同步:首先约定方位,Z轴负半轴为北方,Z轴正半轴为南方,X轴正半轴为东方,X轴负半轴为西方。由于指南针的目的是用于指示鸟瞰图中的方位,我们可以将整个计算过程放在二维空间中进行。

代码示例:

const eye = this.g3d.getEye();const center = this.g3d.getCenter();const v = new ht.Math.Vector2(eye[0], eye[2]);const v2 = new ht.Math.Vector2(center[0], center[2]);const angle = v.sub(v2).angle() - Math.PI / 2;compass.setRotation(-angle);compass.a('angle', angle);compass.a('angle2', angle);

在这段代码中,我们用eye(相机)和center(观测点)构建两个二维向量(ht.Math.Vector2),舍弃掉Y轴的分量。利用向量减法,求得从center指向eye的向量并存入变量v中。角度由angle()方法获取,与x正半轴的夹角(弧度制)相减Math.PI / 2是因为计算的方向与Z轴负半轴(北方)对应。

指南针的旋转角度通过setRotation()方法设置。由于视线的逆时针旋转与指南针的相对运动方向是顺时针旋转,故取负值。

通过HT 2D引擎提供的数据绑定功能,轮盘图标和角度图标的旋转角度可以通过设置compass节点的属性值来实时动态改变。每次视线变化时,需要执行上述计算和设置,可以通过在三维场景组件中增加属性监听器来实现:

graph3dView.addPropertyChangeListener(e => {    if (e.property === 'eye' || e.property === 'center') {        changeCompass();        //...    }});

方位魔方同步:方位魔方用于呈现三维空间中的视线方位。与指南针不同,它也是一个可交互的方位操纵杆,可以方便快捷地将当前视角变为顶视图、侧视图等。

视线改变触发魔方变换:代码示例如下:

graph3dView.addPropertyChangeListener(e => {    if (e.property === 'eye') {        const newValue = e.newValue;        const vEye = new ht.Math.Vector3(newValue[0], newValue[1], newValue[2]).normalize();        graph3dView2.setEye([300 * vEye.x, 300 * vEye.y, 300 * vEye.z]);    }});

在上述代码中,我们通过监听主三维场景(graph3dView)中的eye属性变化来动态改变小场景(graph3dView2)中的eye位置,实现联动效果。e.newValue获取场景视点改变后的值,构建三维向量并归一化,乘以300使距离合适。

点击魔方改变场景视角:要实现点击魔方改变主场景中的视线,需要知道鼠标点击的小魔方哪个面。利用graph3dView.intersectObject(event, data)方法获取点击位置信息,world属性描述点击位置的世界坐标。

代码示例:

graph3dView2.addInteractorListener(event => {    if (event.kind === 'clickData') {        const obj = graph3dView2.intersectObject(event.event, event.data);        if (obj) {            const world = obj.world;            const x = world.x;            const y = world.y;            const z = world.z;            if (Math.abs(x) - Math.abs(y) > 0 && Math.abs(x) - Math.abs(z) > 0) {                if (x > 0) {                    graph3dView2.setEye([300, 0, 0]);                    graph3dView.setEye([this._distance, 0, 0]);                    graph3dView2.setCenter([0, 0, 0]);                    this._g3d.setCenter([0, 0, 0]);                } else {                    graph3dView2.setEye([-300, 0, 0]);                    graph3dView.setEye([-this._distance, 0, 0]);                    graph3dView2.setCenter([0, 0, 0]);                    graph3dView.setCenter([0, 0, 0]);                }            } else if (Math.abs(y) - Math.abs(x) > 0 && Math.abs(y) - Math.abs(z) > 0) {                //...            }        }    }});

点击魔方各个面效果演示:

通过上述方法,点击魔方的不同面会改变主场景的视线方向。点击后,小方块颜色可以通过以下代码禁用选中效果:

const sm = graph3dView2.dm().getSelectionModel();sm.setSelection(null);

总结:直观的方位指示在室内定位、GIS、车站、机场等场景中有广泛应用。利用HT引擎可以轻松实现web 3D的可视化场景。

转载地址:http://whcbz.baihongyu.com/

你可能感兴趣的文章
OpenCV与AI深度学习 | 实战|OpenCV实时弯道检测(详细步骤+源码)
查看>>
OpenCV与AI深度学习 | 实用技巧 | 使用OpenCV进行模糊检测
查看>>
OpenCV与AI深度学习 | 实践教程|旋转目标检测模型-TensorRT 部署(C++)
查看>>
OpenCV与AI深度学习 | 工业缺陷检测中数据标注需要注意的几个事项
查看>>
OpenCV与AI深度学习 | 干货 | 深度学习模型训练和部署的基本步骤
查看>>
OpenCV与AI深度学习 | 手把手教你用Python和OpenCV搭建一个半自动标注工具(详细步骤 + 源码)
查看>>
OpenCV与AI深度学习 | 水下检测+扩散模型:或成明年CVPR最大惊喜!
查看>>
OpenCV与AI深度学习 | 深入浅出了解OCR识别票据原理
查看>>
OpenCV与AI深度学习 | 深度学习检测小目标常用方法
查看>>
OpenCV与AI深度学习 | 超越YOLOv10/11、RT-DETRv2/3!中科大D-FINE重新定义边界框回归任务
查看>>
OpenCV与AI深度学习 | 高效开源的OCR工具:Surya-OCR介绍与使用
查看>>
OpenCV与AI深度学习|16个含源码和数据集的计算机视觉实战项目(建议收藏!)
查看>>
Opencv中KNN背景分割器
查看>>
OpenCV中基于已知相机方向的透视变形
查看>>
OpenCV中的监督学习
查看>>
opencv中读写视频
查看>>
OpenCV中遇到Microsoft C++ 异常 cv::Exception
查看>>
opencv之cv2.findContours和drawContours(python)
查看>>
opencv之namedWindow,imshow出现两个窗口
查看>>
opencv之模糊处理
查看>>