前言

现代工业化的推进在极大加速现代化进程的同时也带来的相应的安全隐患,在传统的可视化监控领域,一般都是基于 Web SCADA 的前端技术来实现 2D 可视化监控,本系统采用 Hightopo 的 HT for Web 产品来构造轻量化的 3D 可视化场景,该 3D 场景从正面展示了一个现代化工厂的现实场景,包括工厂工人的实时位置、电子围栏的范围、现场的安全情况等等,帮助我们直观的了解当前工厂人员的安全状况。

本篇文章通过对工厂可视化场景的搭建和模型的加载,人物实时定位代码的实现、电子围栏和轨迹图的实现进行阐述,帮助我们了解如何通过使用HT实现一个简单的3D电子围栏可视化。

效果预览

工厂人员实时定位效果及电子围栏效果

轨迹图效果图

代码实现

人物模型及场景

项目中使用的人物模型是通过 3dMax 建模生成的,该建模工具可以导出 obj 与 mtl 文件,在 HT 中可以通过解析 obj 与 mtl 文件来生成 3d 场景中的摄像头模型。

项目中场景通过 HT 的 3d 编辑器进行搭建,场景中的模型有些是通过 HT 建模,有些通过 3dMax 建模,之后导入 HT 中。

绘制电子围栏

场景中的电子围栏并不是使用3dMax搭建的模型,HT提供了多种基础形体类型供用户建模使用,不同于传统的3D建模方式,HT的建模核心都是基于API的接口方式, 通过预定义的图元类型和参数接口,进行设置达到三维模型的构建。根据形状,我将电子围栏分成圆柱、长方体和底部为多边形的棱柱。

以下是我绘制电子围栏的相关伪代码:

1 G.makeShapes = function (data, typeName, color, lastColor, g3dDm) {

2 //data是包含电子围栏图形信息的json对象数组

3 let shapes = data;

4 for (let i = 0; i < shapes.length; i++) {

5 let shape = shapes[i];

6 let type = Number(shape['type']);

7 let x = Number(shape['x']);

8 let y = Number(shape['y']);

9 let z = Number(shape['z']);

10 let width = Number(shape['width']);

11 let height = Number(shape['height']);

12 let tall = Number(shape['tall']);

13 let radius = Number(shape['radius']);

14 let vertexX = shape['vertexX'];

15 let vertexY = shape['vertexY'];

16 let nodePoints = [];

17 let p3 = [];

18 let s3 = [];

19 let centerX = 0;

20 let centerY = 0;

21 let centerZ = 0;

22 let node = new ht.Node();

23 node.setTag(typeName + i);

24 switch (type) {

25 //第一种形状:圆柱

26 case 1:

27 p3 = [-x, tall / 2, -y];

28 s3 = [radius, tall, radius];

29 //定义电子围栏样式

30 node.s({

31 "shape3d": "cylinder",

32 "shape3d.color": color,

33 "shape3d.transparent": true,

34 "shape3d.reverse.color": color,

35 "shape3d.top.color": color,

36 "shape3d.top.visible": false,

37 "shape3d.bottom.color": color,

38 "shape3d.from.color": color,

39 "shape3d.to.color": color

40 });

41 node.p3(p3); //设置三维坐标

42 node.s3(s3); //设置形状信息

43 break;

44 //第二种形状:长方体

45 case 2:

46 centerX = x - width / 2;

47 centerY = y - height / 2;

48 centerZ = z + tall / 2;

49 p3 = [-Number(centerX) - width, Number(centerZ), -Number(centerY) - height];

50 s3 = [width, tall, height];

51 node.s({

52 "all.color": color,

53 "all.reverse.color": color,

54 "top.visible": false,

55 "all.transparent": true

56 });

57 node.p3(p3);

58 node.s3(s3);

59 break;

60 //第三种形状:底部为不规则形状的等高体

61 case 3:

62 let segments = [];

63 for (let i = 0; i < vertexX.length; i++) {

64 let x = -vertexX[i];

65 let y = -vertexY[i];

66 let newPoint = { x: x, y: y };

67 nodePoints.push(newPoint);

68 //1: moveTo,占用1个点信息,代表一个新路径的起点

69 if (i === 0) {

70 segments.push(1);

71 }

72 else {

73 //2: lineTo,占用1个点信息,代表从上次最后点连接到该点

74 segments.push(2);

75 if (i === vertexX.length - 1) {

76 //5: closePath,不占用点信息,代表本次路径绘制结束,并闭合到路径的起始点

77 segments.push(5);

78 }

79 }

80 }

81 node = new ht.Shape();

82 node.setTag(typeName + i);

83 node.s({

84 'shape.background': lastColor,

85 'shape.border.width': 10,

86 'shape.border.color': lastColor,

87 'all.color': lastColor,

88 "all.transparent": true,

89 'all.opacity': 0.3,

90 });

91 p3 = [nodePoints[0]['x'], tall / 2, nodePoints[0]['y']];

92 node.p3(p3);

93 node.setTall(tall);

94 node.setThickness(5);

95 node.setPoints(nodePoints); //node设置点集位置信息

96 node.setSegments(segments); //node设置点集连接规则

97 break;

98 }

99 g3dDm.add(node);

100 }

101 }

考虑到电子围栏在某些情况下可能会影响到对人物位置的观察,设置了隐藏电子围栏的功能。在HT中用户可以自定义设置标签Tag作为模型唯一的标识,我将所有的电子围栏模型的标签前缀都统一并且保存在fenceName中,需要隐藏的时候则遍历所有标签名称前缀为fenceName的模型,并且根据模型种类的不同设置不同的隐藏方式。

以下是相关伪代码:

1 g3dDm.each((data) => {

2 if (data.getTag() && data.getTag().substring(0, 4) === fenceName) {

3 if (data.s('all.opacity') === '0') {

4 data.s('all.opacity', '0.3');

5 }

6 else {

7 data.s('shape3d.visible', true);

8 data.s('all.visible', true);

9 data.s("2d.visible", true);

10 data.s("3d.visible", true);

11 }

12 }

13 });

人物模型实时定位

因为项目使用的是http协议获取数据,因此使用定时器定时刷新人物数据信息,HT有设置节点位置的setPosition3d方法,因此不做过多介绍,但是人物节点的位置的刷新还包括人物的朝向,因此每次人物移动都需要和上次位置进行比对,计算出偏移的角度。

相关伪代码如下:

1 // 刷新数据的人物结点与原来的人物节点标签相同,则存在做位置更新

2 if (realInfoData.tagId === tag.getTag()) {

3 //计算位置朝向偏移参数

4 let angleNumber = Math.atan2(((-p3[2]) - (-tag.p3()[2])), ((-p3[0]) - (-tag.p3()[0])));

5 //如果在原地就不转向,判断人物在平面位置是否发生变化

6 if (p3[0] !== tag.p3()[0] || p3[2] !== tag.p3()[2]) {

7 if (angleNumber > 0) {

8 angleNumber = Math.PI - angleNumber;

9 } else {

10 angleNumber = -Math.PI - angleNumber;

11 }

12 //设置人物朝向

13 tag.setRotation3d(0, angleNumber + Math.PI / 2, 0);

14 }

15 //设置人物位置

16 tag.p3(p3);

17 }

人物触发警报

当人物触发警报时,有2种方式同时提醒系统使用者。一是人物头上的面板颜色发生改变,并且显示报警信息。

相关代码如下:

1 switch(obj.alarmType){

2 case null:

3 if(panel){//无警报

4 panel.a('alarmContent','');

5 panel.a('bg','rgba(6,13,36,0.80)');

6 }

7 break;

8 case '0':

9 panel.a('alarmContent','进入围栏');

10 panel.a('bg','rgb(212,0,0)');

11 break;

12 case '1':

13 panel.a('alarmContent','SOS');

14 panel.a('bg','rgb(212,0,0)');

15 break;

16 case '2':

17 panel.a('alarmContent',''); //离开围栏

18 panel.a('bg','rgba(6,13,36,0.80)');

19 break;

20 case '3':

21 panel.a('alarmContent','长时间未动');

22 panel.a('bg','rgb(212,0,0)');

23 break;

24 }

二是页面的右侧面板会增加警报信息。

相关代码如下:

1 data.a('text', info);

2 list.dm().add(data);

轨迹图轨迹实现原理

在发生警报后,需要根据人物的轨迹图回溯发生警报的来龙去脉。如果使用根据点集每走一步就绘制一个canvas脚步节点的方式去重现轨迹,很容易造成节点绘制过多,页面卡顿的情况,因此我使用一整条管道的方式代替一个人物的所有脚步节点,使用管道的好处是,每个人物的轨迹图从开始到结束只有一个管道的图元信息,因此对页面的渲染更加友好和流畅。

生成管道轨迹的代码如下:

1 //生成轨迹

2 this.ployLines[i] = new ht.Polyline();

3 this.ployLines[i].setParent(node);

4 this.points[i] = [];

5 this.points[i].push({ x: p3[0], y: p3[2], e: p3[1] -50 });

6 this.ployLines[i].setPoints(this.points[i]);

7 this.ployLines[i].s({

8 'shape.border.color': 'red'

9 });

10 g3dDm.add(this.ployLines[i]);

人物前进一步,则往管道的点集中推进一个点的坐标,同时绘制新的管道部分。同理,人物后退一步,则管道的点集中推出当前最后一个点的坐标,同时管道失去最后两点连接的部分。另外我通过使用定时器,对轨迹图的前进和后退分别做了快进和快退的处理。以下为轨迹图的运行效果:

关于找一找教程网

本站文章仅代表作者观点,不代表本站立场,所有文章非营利性免费分享。

本站提供了软件编程、网站开发技术、服务器运维、人工智能等等IT技术文章,希望广大程序员努力学习,让我们用科技改变世界。

[基于H5与webGL的 3d 电子围栏展示]http://www.zyiz.net/tech/detail-105610.html

java 电子围栏_基于H5与webGL的 3d 电子围栏展示相关推荐

  1. 基于 HTML5 的 WebGL 自定义 3D 摄像头监控模型

    2019独角兽企业重金招聘Python工程师标准>>> 前言 随着视频监控联网系统的不断普及和发展, 网络摄像机更多的应用于监控系统中,尤其是高清时代的来临,更加快了网络摄像机的发展 ...

  2. 租车java 查询_基于java实现租车管理系统

    概述 基于java + swing + JFrame 的图书馆管理系统,租车,还车,管理员管理用户,付款等. 部分代码 public class Login extends JFrame { priv ...

  3. java r$_基于javacv的人脸检测Demo

    [实例简介] 基于javacv的人脸检测Demo,参考文章:http://blog.csdn.net/viviwen123/article/details/6386302#reply [实例截图] [ ...

  4. 成绩查询系统源java代码_基于jsp的成绩查询系统-JavaEE实现成绩查询系统 - java项目源码...

    基于jsp+servlet+pojo+mysql实现一个javaee/javaweb的成绩查询系统, 该项目可用各类java课程设计大作业中, 成绩查询系统的系统架构分为前后台两部分, 最终实现在线上 ...

  5. 运动会成绩管理java代码_基于jsp的运动会成绩管理-JavaEE实现运动会成绩管理 - java项目源码...

    基于jsp+servlet+pojo+mysql实现一个javaee/javaweb的运动会成绩管理, 该项目可用各类java课程设计大作业中, 运动会成绩管理的系统架构分为前后台两部分, 最终实现在 ...

  6. 事件驱动java实现_基于spring实现事件驱动

    通过阅读该篇博客,你可以了解了解java的反射机制.可以了解如何基于spring生命周期使用自定义注解解决日常研发问题.具体源码可以点击 链接 . 问题描述 在日常研发中,经常会遇见业务A的某个act ...

  7. java 状态机_基于 RAFT 一致性算法的 Java 实现 SOFAJRaft

    SOFAJRaft 是一个基于 RAFT 一致性算法的生产级高性能 Java 实现,支持 MULTI-RAFT-GROUP,适用于高负载低延迟的场景. 使用 SOFAJRaft 你可以专注于自己的业务 ...

  8. redis分布式锁java代码_基于redis实现分布式锁

    " 在上一篇文章中介绍了动态配置定时任务,其中的原理跟spring 定时任务注解@Scheduled一样的,都是通过线程池和定义执行时间来控制.来思考一个问题,如果我们的定时任务在分布式微服 ...

  9. java集成测试_基于TestNG+Mockito及自动装配注解的Spring MVC集成测试

    本文主要总结自己近期在项目中对MVC集成测试的实践及理解,因为先前对这块未实践过.主要参考了官方文档<11.3.6 Spring MVC Test Framework>这一章节内容,涉及到 ...

最新文章

  1. Spring Boot 结合 Redis 缓存
  2. Facebook 开源 Skip,面向对象+函数式编程语言
  3. MTK 驱动开发(30)---Memory 移植
  4. MySQL级联删除和级联修改
  5. 深度装机大师一键重装_教你使用深度装机大师重装win10系统
  6. vimpython配色_你认为最好看的 Vim 配色方案(color scheme)是哪款?
  7. Shell中的括号、方括号、花括号、双括号和双方括号使用场景总结
  8. 视网膜屏 retina屏
  9. Python 如何截取字符函数
  10. python语法详解_关于python:NLTK中解析的英语语法
  11. cropper截图插件(自定义像素的图片并保存本地)
  12. 指标 | 指标波动归因
  13. 懂我的人不需要我解释,不懂我的人我不需要解释。。
  14. Unity3D摄像机(Camera)跟随角色移动的代码控制和演示动画
  15. 赛钛客Cyborg R.A.T.7高度自定游戏鼠标
  16. hdu4899 dp套dp
  17. 股票中的做T的是什么意思?
  18. 什么样的人才培养才能在企业中发挥重要作用?
  19. 油脂集中润滑循环指示器XZQ-1、XZQ-2
  20. 驭势科技吴甘沙:乘用车智能驾驶淘汰赛的七个核心观点

热门文章

  1. 安徽大学大学生创新项目报销流程
  2. 4G物联网模组连接网络大致流程
  3. peppa pig原版_Peppy和MooTools
  4. 说唱 -- 再见大四
  5. 2019年最新版嵌入式开发教程大纲免费分享
  6. 课程linux实验报告,Linux课程综合训练实验报告
  7. 第24章 让唯美的雪花飘扬——三维粒子系统的实现
  8. 手机号注册过,被遗忘的网站有哪些?
  9. 动画专业考一级计算机选什么语种,学校和专业如何选择?学连接32个国家的金牌语种,做国家稀缺的复合型人才!...
  10. 罗克韦尔ABSourceKeyTools工具制作