Vue+Three.js实现三维管道可视化及流动模拟续集

上一篇文章中实现了三维管道的可视化和流动模拟,经过反馈,对大家还是有一定帮助,因此就编写了一个续集,相当于增加了一些常见的通用共性功能,主要在前面的基础上增加了以下功能:
1.新增直角拐弯的管道,工业中很多管道都是横平竖直的,相当于我们装修的水管或电线等,不是曲线而是直线,夹角基本都是90度。
2.新增透明管道和不透明管道的动态模拟,通过材质和透明度属性(transparent)进行设置。
3.新增不同管道采用不同的材质和速度进行流动模拟,相当于管道总支和分支的动态模拟。
4.新增网格显示,便于做对齐校正、对比显示。
5.新增不同管道的点击时的详细信息框显示,比如显示管道名称、管径、长度、流动速度等。

开发环境和之前的一样,实现效果如下:

Vue+Three.js,实现原理和之前类似,通过不断改变管道的Texture实现管道动态流动模拟,不同管道设置不同的Texture和更新速度,重复代码请参加上一篇文章,这里主要显示不同的代码,代码详见pipe4.vue。

核心代码如下:

javascript 复制代码
//pipe4.vue
<template>  
  <div class="home" id="myDiv" ref="container">  
    <div id="objInfor"></div>  
  </div>
</template>
const z=20;//管道垂直下移数量  
export default {  
  name: "pipe4",
  mounted() {  
	  this.init();  
	  this.initGrid();//加入网格  
  },
  methods:{  
  /**  
   * 初始化方法  
   */  
  init() {
	  // 4.Mesh 渲染对象,包括Mesh 几何体 (形状等)和材质。4.1和4.2  
	  this.initTubeModel();
	  //增加鼠标点击事件,用于处理管道信息框的显示
	  document.addEventListener("mousedown",this.getClickObj,false);
	  
  },
  initGrid(){  
  let grid = new THREE.GridHelper( 300, 8, '#bfc7d3', 'rgb(126,151,176)' );  
  grid.position.set(0,-100,-50);//xzy  
  this.scene.add( grid );  
},  
initTubeModel() {  
  //第一条管线数据,可来自实际业务数据  
  var pointsArr = [  
    [42, z, 10],  
    [21, z, 10],  
    [1, z, 24],  
    [-27, z, 24],  
    [-27, z, 18],  
    [-46, z, 19],  
    [-46, z, -4],  
    [-25, z, -6],  
    [-25, z, -19],  
    [-35, z, -20],  
    [-35, z, -26],  
    [-30, z, -30],  
    [3, z, -30],  
    [42, z, -30]  
  ];  
  //第二条管线数据,可来自实际业务数据  
  var pointsArr2 = [  
    [1, z, 10],  
    [1, z, 2],  
    [30, z, 2],  
    [30, z, -10],  
    [40, z, -10],  
    [42, z, -30]  
  ];  
  var curve = createPath(pointsArr);  
  this.createTube(curve,'arrow8.png',0.0066,'管道1');  
  var curve2 = createPath(pointsArr2);  
  this.createTube(curve2,'arrow7.png',0.0036,'管道2');  
},
//createTube进行的重现,主要接受了三个参数,分别为坐标生成的管道对象,材质图像,移动速度,管道名称等。
createTube(curve,textureImage,textureSpeed,name){  
  var tubeGeometry = new THREE.TubeGeometry(curve, 100, 1.5, 200, false);  
  var textureLoader = new THREE.TextureLoader();  
  var texture = textureLoader.load('http://localhost:8082/static/data/'+textureImage); //./ZS箭头.svg  ./arrow.jpg  
  // 设置阵列模式为 RepeatWrapping  texture.wrapS = THREE.RepeatWrapping  
  texture.wrapT = THREE.RepeatWrapping  
  texture.repeat.x = 50;  
  texture.repeat.y = 2;  
  texture.offset.y = 0.3;  
  
  var tubeMaterial = new THREE.MeshPhongMaterial({  
    map: texture,  
    transparent: true,  
    // color: 'rgba(ff,ff,ff,0.05)',//'rgba(237,149,3,0.05)'  
    side: THREE.DoubleSide,  
    opacity: 0.7,  
  });  
  
  // 设置数组材质对象作为网格模型材质参数  
  var mesh = new THREE.Mesh(tubeGeometry, tubeMaterial); //网格模型对象Mesh  
  mesh.position.y = 2;  
  mesh.rotateZ(3.14);  
  mesh.scale.set(2, 2, 2);  
  // 使用加减法可以设置不同的运动方向  
  setInterval(() => {  
    texture.offset.x -= textureSpeed  
  });  
  //添加用户自定义的数据,可自定义增加任意数据,json格式。  
  mesh.userData={'name':name,'radius':tubeGeometry.parameters.radius,'width':200,'speed':textureSpeed*10000};  
  this.scene.add(mesh); //网格模型添加到场景中  
},  
//鼠标点击事件,获取对象信息,对象信息在mesh.userData  
getClickObj(event){  
  //申明raycaster和mouse变量  
  var raycaster = new THREE.Raycaster();  
  var mouse = new THREE.Vector2();  
  //通过鼠标点击的地位计算出raycaster所须要的点的地位,以屏幕核心为原点,值的范畴为-1到1.  
  mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;  
  mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;    
  // 通过鼠标点的地位和以后相机的矩阵计算出raycaster  
  raycaster.setFromCamera( mouse, this.camera );  
  
  // 获取raycaster直线和所有模型相交的数组汇合  
  var intersects = raycaster.intersectObjects( this.scene.children );  
  //有相交物体时  
  if (intersects.length > 0) { //其中数组第一个值的 object属性值就是鼠标放在屏幕上离我们最近的模型  
    console.log('显示');  
    //设置信息  
    infoBox.innerHTML = `<div style=\"background-color: rgba(122,243,215,0.85)\">基本信息</div>  
						名称:${intersects[0].object.userData.name}  
						<br>管径:${intersects[0].object.userData.radius}m  
						<br>速度:${intersects[0].object.userData.speed}m/s  
						<br>长度:${intersects[0].object.userData.width}m`;
    objInfor.style.display = "block";  
    console.log(event.clientX);  
    objInfor.style.left = event.clientX + "px"; //记得一定要拼接px  
    objInfor.style.top = event.clientY + "px"  
  }  
}
}
}
// 根据三维点数据形成三维曲线路径。  
function createPath(pointsArr) {  
  pointsArr = pointsArr.map((point) => new THREE.Vector3(...point)); // 将参数数组转换成点数组的形式  
  
  // 方法一:自定义三维路径 curvePath  const path = new THREE.CurvePath();  
  for (let i = 0; i < pointsArr.length - 1; i++) {  
    const lineCurve = new THREE.LineCurve3(pointsArr[i], pointsArr[i + 1]); // 每两个点之间形成一条三维直线  
    path.curves.push(lineCurve); // curvePath有一个curves属性,里面存放组成该三维路径的各个子路径  
  }  
  return path;  
}
相关推荐
JUNAI_Strive_ving10 分钟前
番茄小说逆向爬取
javascript·python
看到请催我学习19 分钟前
如何实现两个标签页之间的通信
javascript·css·typescript·node.js·html5
twins352039 分钟前
解决Vue应用中遇到路由刷新后出现 404 错误
前端·javascript·vue.js
qiyi.sky1 小时前
JavaWeb——Vue组件库Element(3/6):常见组件:Dialog对话框、Form表单(介绍、使用、实际效果)
前端·javascript·vue.js
煸橙干儿~~1 小时前
分析JS Crash(进程崩溃)
java·前端·javascript
哪 吒1 小时前
华为OD机试 - 几何平均值最大子数(Python/JS/C/C++ 2024 E卷 200分)
javascript·python·华为od
安冬的码畜日常1 小时前
【D3.js in Action 3 精译_027】3.4 让 D3 数据适应屏幕(下)—— D3 分段比例尺的用法
前端·javascript·信息可视化·数据可视化·d3.js·d3比例尺·分段比例尺
杨荧2 小时前
【JAVA开源】基于Vue和SpringBoot的洗衣店订单管理系统
java·开发语言·vue.js·spring boot·spring cloud·开源
l1x1n02 小时前
No.3 笔记 | Web安全基础:Web1.0 - 3.0 发展史
前端·http·html
Q_w77422 小时前
一个真实可用的登录界面!
javascript·mysql·php·html5·网站登录