博客
关于我
分享 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/

你可能感兴趣的文章
Nginx配置实例-负载均衡实例:平均访问多台服务器
查看>>
Nginx配置文件nginx.conf中文详解(总结)
查看>>
Nginx配置负载均衡到后台网关集群
查看>>
ngrok | 内网穿透,支持 HTTPS、国内访问、静态域名
查看>>
NHibernate学习[1]
查看>>
NHibernate异常:No persister for的解决办法
查看>>
NIFI1.21.0_Mysql到Mysql增量CDC同步中_日期类型_以及null数据同步处理补充---大数据之Nifi工作笔记0057
查看>>
NIFI1.21.0_NIFI和hadoop蹦了_200G集群磁盘又满了_Jps看不到进程了_Unable to write in /tmp. Aborting----大数据之Nifi工作笔记0052
查看>>
NIFI1.21.0通过Postgresql11的CDC逻辑复制槽实现_指定表多表增量同步_增删改数据分发及删除数据实时同步_通过分页解决变更记录过大问题_02----大数据之Nifi工作笔记0054
查看>>
NIFI从MySql中增量同步数据_通过Mysql的binlog功能_实时同步mysql数据_根据binlog实现数据实时delete同步_实际操作04---大数据之Nifi工作笔记0043
查看>>
NIFI从MySql中增量同步数据_通过Mysql的binlog功能_实时同步mysql数据_配置binlog_使用处理器抓取binlog数据_实际操作01---大数据之Nifi工作笔记0040
查看>>
NIFI从MySql中增量同步数据_通过Mysql的binlog功能_实时同步mysql数据_配置数据路由_实现数据插入数据到目标数据库_实际操作03---大数据之Nifi工作笔记0042
查看>>
NIFI从MySql中离线读取数据再导入到MySql中_03_来吧用NIFI实现_数据分页获取功能---大数据之Nifi工作笔记0038
查看>>
NIFI从PostGresql中离线读取数据再导入到MySql中_带有数据分页获取功能_不带分页不能用_NIFI资料太少了---大数据之Nifi工作笔记0039
查看>>
NIFI同步MySql数据_到SqlServer_错误_驱动程序无法通过使用安全套接字层(SSL)加密与SQL Server_Navicat连接SqlServer---大数据之Nifi工作笔记0047
查看>>
Nifi同步过程中报错create_time字段找不到_实际目标表和源表中没有这个字段---大数据之Nifi工作笔记0066
查看>>
NIFI大数据进阶_FlowFile拓扑_对FlowFile内容和属性的修改删除添加_介绍和描述_以及实际操作---大数据之Nifi工作笔记0023
查看>>
NIFI大数据进阶_NIFI的模板和组的使用-介绍和实际操作_创建组_嵌套组_模板创建下载_导入---大数据之Nifi工作笔记0022
查看>>
NIFI大数据进阶_NIFI监控的强大功能介绍_处理器面板_进程组面板_summary监控_data_provenance事件源---大数据之Nifi工作笔记0025
查看>>
NIFI大数据进阶_NIFI集群知识点_集群的断开_重连_退役_卸载_总结---大数据之Nifi工作笔记0018
查看>>