3D на основе внутреннего позиционирования и электронный забор Н5 WebGL

предисловие

Современная индустриализация заранее значительно ускорить процесс модернизации, он также приносит соответствующие риски безопасности в традиционном визуальном наблюдении, как правило, основаны на Web SCADA фронтальной технологии для достижения 2D визуального контроля, система использует HT для Hightopo веб-продукт изготовлен из легкого 3D визуализации сцены, 3D-сцены из передней панели показывает реальную картину современного завода, крытый местоположение, включая в режиме реального времени местоположение заводских рабочих, объем электронного забора, условия безопасности сайта и т.д., чтобы помочь нашим интуитивным понять текущее состояние безопасности персонала завода.

Загрузить эту статью Plant Visualization сцены для создания и моделей, для достижения символов в режиме реального времени коды в помещении позиционирования для достижения электронного забора и траектории приведены, чтобы помочь нам понять, как реализовать простой 3D крытого позиционирования и электронный забор посредством использования HT визуализация.

Следующие пункты Адрес: на основе HTML5 WebGL 3D промышленного электронного забора , траектории

Результаты предварительного просмотра

Растительные кадровые эффекты и в режиме реального времени эффект позиционирования электронный забор

Траектории визуализации

Траектории

реализация кода

Модели персонажей и сцены

Модели персонажей, используемые в проекте создаются путем моделирования 3dMax, инструмент моделирования может экспортировать OBJ и MTL файлы могут быть сгенерированы в HT модели камеры 3d сцены, анализируя OBJ и MTL файлов.

Проект строительства сцены по ХТ в 3d редактора, сцены некоторых из модели путем моделирования HT, некоторые моделированием 3dMax, после импорта HT.

Рисование электронного забора

Модель сцены Электронный забор построен 3dMax не используется, ХТ вариант обеспечивает интерфейс для пользователя, чтобы ввести более базовую модель тела используется, в отличие от обычных 3D моделирования, моделирование ядра API-НТ основаны на предварительно определенные параметры и типы интерфейсов, элементов для построения трехмерной модели обеспечивается достижение. Формы, электронный забор я в цилиндрическую, прямоугольную, и многоугольной призмы снизу.

Вот псевдокод рисую электронный забор:

Скопировать код
  1 G.makeShapes = функция (данные, TypeName, цвет, 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]);
Скопировать код

 

Перед дальнейшим фигур, трубопровод до точки фокуса для продвижения координаты точки, при создании нового участка трубы. Кроме того, персонажи шага назад, точка фокусировки запуска трубопровода координаты последней точки тока, в то время как последние два трубопровода потерять некоторые связи. Кроме того, я с помощью таймера, для прямых и обратных траекторий были сделаны для быстрой перемотки вперед и назад процесс. Следующие операционные результаты за траекториями:

 

рекомендация

отwww.cnblogs.com/htdaydayup/p/11669417.html
рекомендация