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

你可能感兴趣的文章
Netty源码—4.客户端接入流程一
查看>>
Netty源码—4.客户端接入流程二
查看>>
Netty源码—5.Pipeline和Handler一
查看>>
Netty源码—5.Pipeline和Handler二
查看>>
Netty源码—6.ByteBuf原理一
查看>>
Netty源码—6.ByteBuf原理二
查看>>
Netty源码—7.ByteBuf原理三
查看>>
Netty源码—7.ByteBuf原理四
查看>>
Netty源码—8.编解码原理一
查看>>
Netty源码—8.编解码原理二
查看>>
Netty源码解读
查看>>
Netty的Socket编程详解-搭建服务端与客户端并进行数据传输
查看>>
Netty相关
查看>>
Netty遇到TCP发送缓冲区满了 写半包操作该如何处理
查看>>
Netty:ChannelPipeline和ChannelHandler为什么会鬼混在一起?
查看>>
Netty:原理架构解析
查看>>
Network Dissection:Quantifying Interpretability of Deep Visual Representations(深层视觉表征的量化解释)
查看>>
Network Sniffer and Connection Analyzer
查看>>
Network 灰鸽宝典【目录】
查看>>
NetworkX系列教程(11)-graph和其他数据格式转换
查看>>