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

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

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

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

//pipe4.vue

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 = `
基本信息
名称:${intersects[0].object.userData.name}
管径:${intersects[0].object.userData.radius}m
速度:${intersects[0].object.userData.speed}m/s
长度:${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; }

你可能感兴趣的:(数据应用,数字孪生,3D学习,javascript,vue.js,前端,数字孪生)