基于HTML5 WebGL的工业化3D电子围栏
前言
现代工业化的推进在极大加速现代化进程的同时也带来的相应的安全隐患,在传统的可视化监控领域,一般都是基于 Web SCADA 的前端技术来实现 2D 可视化监控,本系统采用 Hightopo 的 HT for Web 产品来构造轻量化的 3D 可视化场景,该 3D 场景从正面展示了一个现代化工厂的现实场景,包括工厂工人的实时位置、电子围栏的范围、现场的安全情况等等,帮助我们直观的了解当前工厂人员的安全状况。
本篇文章通过对工厂可视化场景的搭建和模型的加载,人物实时定位代码的实现、电子围栏和轨迹图的实现进行阐述,帮助我们了解如何通过使用HT实现一个简单的3D电子围栏可视化。
以下是项目地址:基于HTML5 WebGL的工业化3D电子围栏、轨迹图
效果预览
工厂人员实时定位效果及电子围栏效果
轨迹图效果图
代码实现
人物模型及场景
项目中使用的人物模型是通过 3dMax 建模生成的,该建模工具可以导出 obj 与 mtl 文件,在 HT 中可以通过解析 obj 与 mtl 文件来生成 3d 场景中的摄像头模型。
项目中场景通过 HT 的 3d 编辑器进行搭建,场景中的模型有些是通过 HT 建模,有些通过 3dMax 建模,之后导入 HT 中。
绘制电子围栏
场景中的电子围栏并不是使用3dMax搭建的模型,HT提供了多种基础形体类型供用户建模使用,不同于传统的3D建模方式,HT的建模核心都是基于API的接口方式, 通过预定义的图元类型和参数接口,进行设置达到三维模型的构建。根据形状,我将电子围栏分成圆柱、长方体和底部为多边形的棱柱。
以下是我绘制电子围栏的相关伪代码:
G.makeShapes = function (data, typeName, color, lastColor, g3dDm) {
//data是包含电子围栏图形信息的json对象数组
let shapes = data;
for (let i = 0; i < shapes.length; i++) {
let shape = shapes[i];
let type = Number(shape['type']);
let x = Number(shape['x']);
let y = Number(shape['y']);
let z = Number(shape['z']);
let width = Number(shape['width']);
let height = Number(shape['height']);
let tall = Number(shape['tall']);
let radius = Number(shape['radius']);
let vertexX = shape['vertexX'];
let vertexY = shape['vertexY'];
let nodePoints = [];
let p3 = [];
let s3 = [];
let centerX = 0;
let centerY = 0;
let centerZ = 0;
let node = new ht.Node();
node.setTag(typeName + i);
switch (type) {
//第一种形状:圆柱
case 1:
p3 = [-x, tall / 2, -y];
s3 = [radius, tall, radius];
//定义电子围栏样式
node.s({
"shape3d": "cylinder",
"shape3d.color": color,
"shape3d.transparent": true,
"shape3d.reverse.color": color,
"shape3d.top.color": color,
"shape3d.top.visible": false,
"shape3d.bottom.color": color,
"shape3d.from.color": color,
"shape3d.to.color": color
});
node.p3(p3); //设置三维坐标
node.s3(s3); //设置形状信息
break;
//第二种形状:长方体
case 2:
centerX = x - width / 2;
centerY = y - height / 2;
centerZ = z + tall / 2;
p3 = [-Number(centerX) - width, Number(centerZ), -Number(centerY) - height];
s3 = [width, tall, height];
node.s({
"all.color": color,
"all.reverse.color": color,
"top.visible": false,
"all.transparent": true
});
node.p3(p3);
node.s3(s3);
break;
//第三种形状:底部为不规则形状的等高体
case 3:
let segments = [];
for (let i = 0; i < vertexX.length; i++) {
let x = -vertexX[i];
let y = -vertexY[i];
let newPoint = { x: x, y: y };
nodePoints.push(newPoint);
//1: moveTo,占用1个点信息,代表一个新路径的起点
if (i === 0) {
segments.push(1);
}
else {
//2: lineTo,占用1个点信息,代表从上次最后点连接到该点
segments.push(2);
if (i === vertexX.length - 1) {
//5: closePath,不占用点信息,代表本次路径绘制结束,并闭合到路径的起始点
segments.push(5);
}
}
}
node = new ht.Shape();
node.setTag(typeName + i);
node.s({
'shape.background': lastColor,
'shape.border.width': 10,
'shape.border.color': lastColor,
'all.color': lastColor,
"all.transparent": true,
'all.opacity': 0.3,
});
p3 = [nodePoints[0]['x'], tall / 2, nodePoints[0]['y']];
node.p3(p3);
node.setTall(tall);
node.setThickness(5);
node.setPoints(nodePoints); //node设置点集位置信息
node.setSegments(segments); //node设置点集连接规则
break;
}
g3dDm.add(node);
}
}
考虑到电子围栏在某些情况下可能会影响到对人物位置的观察,设置了隐藏电子围栏的功能。在HT中用户可以自定义设置标签Tag作为模型唯一的标识,我将所有的电子围栏模型的标签前缀都统一并且保存在fenceName中,需要隐藏的时候则遍历所有标签名称前缀为fenceName的模型,并且根据模型种类的不同设置不同的隐藏方式。
以下是相关伪代码:
g3dDm.each((data) => {
if (data.getTag() && data.getTag().substring(0, 4) === fenceName) {
if (data.s('all.opacity') === '0') {
data.s('all.opacity', '0.3');
}
else {
data.s('shape3d.visible', true);
data.s('all.visible', true);
data.s("2d.visible", true);
data.s("3d.visible", true);
}
}
});
人物模型实时定位
因为项目使用的是http协议获取数据,因此使用定时器定时刷新人物数据信息,HT有设置节点位置的setPosition3d方法,因此不做过多介绍,但是人物节点的位置的刷新还包括人物的朝向,因此每次人物移动都需要和上次位置进行比对,计算出偏移的角度。
相关伪代码如下:
// 刷新数据的人物结点与原来的人物节点标签相同,则存在做位置更新
if (realInfoData.tagId === tag.getTag()) {
//计算位置朝向偏移参数
let angleNumber = Math.atan2(((-p3[2]) - (-tag.p3()[2])), ((-p3[0]) - (-tag.p3()[0])));
//如果在原地就不转向,判断人物在平面位置是否发生变化
if (p3[0] !== tag.p3()[0] || p3[2] !== tag.p3()[2]) {
if (angleNumber > 0) {
angleNumber = Math.PI - angleNumber;
} else {
angleNumber = -Math.PI - angleNumber;
}
//设置人物朝向
tag.setRotation3d(0, angleNumber + Math.PI / 2, 0);
}
//设置人物位置
tag.p3(p3);
}
人物触发警报
当人物触发警报时,有2种方式同时提醒系统使用者。一是人物头上的面板颜色发生改变,并且显示报警信息。
相关代码如下:
switch(obj.alarmType){
case null:
if(panel){//无警报
panel.a('alarmContent','');
panel.a('bg','rgba(6,13,36,0.80)');
}
break;
case '0':
panel.a('alarmContent','进入围栏');
panel.a('bg','rgb(212,0,0)');
break;
case '1':
panel.a('alarmContent','SOS');
panel.a('bg','rgb(212,0,0)');
break;
case '2':
panel.a('alarmContent',''); //离开围栏
panel.a('bg','rgba(6,13,36,0.80)');
break;
case '3':
panel.a('alarmContent','长时间未动');
panel.a('bg','rgb(212,0,0)');
break;
}
二是页面的右侧面板会增加警报信息。
相关代码如下:
data.a('text', info);
list.dm().add(data);
轨迹图轨迹实现原理
在发生警报后,需要根据人物的轨迹图回溯发生警报的来龙去脉。如果使用根据点集每走一步就绘制一个canvas脚步节点的方式去重现轨迹,很容易造成节点绘制过多,页面卡顿的情况,因此我使用一整条管道的方式代替一个人物的所有脚步节点,使用管道的好处是,每个人物的轨迹图从开始到结束只有一个管道的图元信息,因此对页面的渲染更加友好和流畅。
生成管道轨迹的代码如下:
//生成轨迹
this.ployLines[i] = new ht.Polyline();
this.ployLines[i].setParent(node);
this.points[i] = [];
this.points[i].push({ x: p3[0], y: p3[2], e: p3[1] -50 });
this.ployLines[i].setPoints(this.points[i]);
this.ployLines[i].s({
'shape.border.color': 'red'
});
g3dDm.add(this.ployLines[i]);
人物前进一步,则往管道的点集中推进一个点的坐标,同时绘制新的管道部分。同理,人物后退一步,则管道的点集中推出当前最后一个点的坐标,同时管道失去最后两点连接的部分。另外我通过使用定时器,对轨迹图的前进和后退分别做了快进和快退的处理。以下为轨迹图的运行效果:
基于HTML5 WebGL的工业化3D电子围栏的更多相关文章
- 基于 HTML5 WebGL 的地铁站 3D 可视化系统
前言 工业互联网,物联网,可视化等名词在我们现在信息化的大背景下已经是耳熟能详,日常生活的交通,出行,吃穿等可能都可以用信息化的方式来为我们表达,在传统的可视化监控领域,一般都是基于 Web SCAD ...
- 基于 HTML5 WebGL 的挖掘机 3D 可视化应用
前言 在工业互联网以及物联网的影响下,人们对于机械的管理,机械的可视化,机械的操作可视化提出了更高的要求.如何在一个系统中完整的显示机械的运行情况,机械的运行轨迹,或者机械的机械动作显得尤为的重要,因 ...
- 基于 HTML5 WebGL 的加油站 3D 可视化监控
前言 随着数字化,工业互联网,物联网的发展,我国加油站正向有人值守,无人操作,远程控制的方向发展,传统的人工巡查方式逐渐转变为以自动化控制为主的在线监控方式,即采用数据采集与监控系统 SCADA.SC ...
- 基于 HTML5 + WebGL 的地铁 3D 可视化系统
前言 工业互联网,物联网,可视化等名词在我们现在信息化的大背景下已经是耳熟能详,日常生活的交通,出行,吃穿等可能都可以用信息化的方式来为我们表达,在传统的可视化监控领域,一般都是基于 Web SCAD ...
- 基于 HTML5 WebGL 与 WebVR 3D 虚实现实的可视化培训系统
前言 2019 年 VR, AR, XR, 5G, 工业互联网等名词频繁出现在我们的视野中,信息的分享与虚实的结合已经成为大势所趋,5G 是新一代信息通信技术升级的重要方向,工业互联网是制造业转型升级 ...
- 基于 HTML5 WebGL + WebVR 的 3D 虚实现实可视化培训系统
前言 2019 年 VR, AR, XR, 5G, 工业互联网等名词频繁出现在我们的视野中,信息的分享与虚实的结合已经成为大势所趋,5G 是新一代信息通信技术升级的重要方向,工业互联网是制造业转型升级 ...
- 基于 HTML5 WebGL + WebVR 的 3D 虚实现实可视化系统
前言 2019 年 VR, AR, XR, 5G, 工业互联网等名词频繁出现在我们的视野中,信息的分享与虚实的结合已经成为大势所趋,5G 是新一代信息通信技术升级的重要方向,工业互联网是制造业转型升级 ...
- 基于 HTML5 WebGL 的发动机 3D 可视化系统
前言 工业机械产品大多体积庞大.运输成本高,在参加行业展会或向海外客户销售时,如果没有实物展示,仅凭静态.简单的图片说明书介绍,无法让客户全面了解产品,不仅工作人员制作麻烦,客户看得也费力.如 ...
- B/S 端基于 HTML5 + WebGL 的 VR 3D 机房数据中心可视化
前言 在 3D 机房数据中心可视化应用中,随着视频监控联网系统的不断普及和发展, 网络摄像机更多的应用于监控系统中,尤其是高清时代的来临,更加快了网络摄像机的发展和应用. 在监控摄像机数量的不断庞大的 ...
随机推荐
- 牛客 136J-洋灰三角 +高中数学博大精深
参考学习:http://www.cnblogs.com/l609929321/p/9500814.html 牛客 136J-洋灰三角 题意: 在一个1 * n的棋盘中,第一格放1,之后的每一个放前一个 ...
- HDU-2018多校7th-1011-Swordsman 附杜教fread代码
HDU-6396 题意: 背景是打怪升级的故事,有k个不同属性的初始的能力值,每只怪物也有相同个数的能力值,你只能放倒k个能力值都比怪物大的,每放倒一个怪物,都可以得到相应的k个能力值. 思路: 根据 ...
- The Suspects POJ1611
The Suspects Time Limit: 1000MS Memory Limit: 20000K Total Submissions: 36417 Accepted: 17681 De ...
- codeforces 779 D. String Game(二分)
题目链接:http://codeforces.com/contest/779/problem/D 题意:给你一段操作序列,按顺序依次删掉字符串1中相应位置的字符,问你最多能按顺序删掉多少个字符,使得s ...
- CF995B Suit and Tie 贪心 第十三
Suit and Tie time limit per test 2 seconds memory limit per test 256 megabytes input standard input ...
- codeforces 919C Seat Arrangements 思维模拟
C. Seat Arrangements time limit per test 1 second memory limit per test 256 megabytes input standard ...
- 爬虫反爬之代理IP
爬虫反爬之代理IP 代理IP其实本就是在requests模块中的参数 定义: 代替原来的IP地址去对接网络的IP地址. 作用: 隐藏自身真实IP,避免被封. 获取代理IP网站 西刺代理.快代理.全网代 ...
- 使用EF6简实现多租户的应用
什么是多租户 网上有好多解释,有些上升到了架构设计,让你觉得似乎非常高深莫测,特别是目前流行的ABP架构中就有提到多租户(IMustHaveTenant),其实说的简单一点就是再每一张数据库的表中添加 ...
- 微信小程序一步一步获取UnionID,实现自动登录
思路: 1.小程序端获取用户ID,发送至后台 2.后台查询用户ID,如果找到了该用户,返回Token,没找到该用户,保存到数据库,并返回Token 小程序端如何获取用户ID: 小程序端 wx.getU ...
- MyBatis基础之几道常见面试题详解
(原文链接:http://www.studyshare.cn/blog/details/1178/1 一.开发中到底应该使用resultType还是resultMap? 强制使用resultMap,不 ...