3D电子围栏这样搭建,效率提高90%
现代工业化的推进在极大加速现代化进程的同时也带来的相应的安全隐患,在传统的可视化监控领域,一般都是基于 Web SCADA 的前端技术来实现 2D 可视化监控。
本系统采用 Hightopo 的 HT for Web 产品来构造轻量化的 3D 可视化场景,该 3D 场景从正面展示了一个现代化工厂的现实场景,包括工厂工人的实时位置、电子围栏的范围、现场的安全情况等等,帮助我们直观的了解当前工厂人员的安全状况。
本篇文章通过对工厂可视化场景的搭建和模型的加载,人物实时定位代码的实现、电子围栏和轨迹图的实现进行阐述,帮助我们了解如何通过使用HT实现一个简单的3D电子围栏可视化。
以下是项目地址:基于HTML5 WebGL的工业化3D电子围栏、轨迹图
效果预览
工厂人员实时定位效果及电子围栏效果
更多内容:https://www.hightopo.com/demos/index.html
轨迹图效果图
代码实现
人物模型及场景
项目中使用的人物模型是通过 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 });
提交
大数据+可视化,智慧工厂这样做事半功倍
工业4.0:无人机3D可视化系统的应用
能源管理可视化破冰而出
图扑智慧农业效率事半功倍
100%省力让城市管廊运维变得轻松