- 初始思路及其学习流程;
1.1分析
要求:
搭建一个根据长宽高展示建筑物的模型,然后选取lps等级在该建筑物上绘制对应的网格线,展示间隔距离中的网格法,以便人们理解;当用户想要调整网格的时候,有两种方式;一是调整lps等级;而是直接操作网格的网格线;然后根据修改后的网格线及其交点,计算得出每个交点的间隔距离值。
实现:
在three的画布中根据长宽高绘制一个长方体来代替建筑物;根据下拉选择lps等级绘制网格线,监听lps等级再它进行变动时重绘网格;或是点击修改参数调整网格位置,根据鼠标选中需要调整网格线,然后鼠标拖动到想到的位置,确定根据当前的调整重绘网格交点;最后计算间隔距离得出结果绘制对应数据3d显示在对应交点处。
1.2 学习流程
实现输入长宽高搭建长方体;监听长宽高的数值,模型根据长宽高的改动而改变;
实现生成网格线条;根据长宽的数据和lps等级,用长宽除以lps等级,得到网格线条的间距,然后利用前后两点坐标分别生成网格对应的排和列;监听lps等级的变化,数据变动删除当前数据及时更新长方体网格数量变动;
实现拖动线条;拖动线条首先得获取鼠标选取物体,利用光线投射Raycaster方法获取点击的物体;然后再根据物体关键字去匹配物体;利用DragControls方法来拖动该物体
实现差值diff计算;全局定义一个变量;在dragstart的时候记录上一次或者第一次拖动物体position;然后在用dragend记录最后位置,利用最后位置减去记录的上一次位置得到diff值,将交点坐标与长度进行修改;
-
- 学习资料
Three中文网站:1. threejs文件包下载和目录简介 | Three.js中文网;
B站也有相关教学视频:[WebGL Three.js从入门到门内] 1-1介绍与第一个案例_哔哩哔哩_bilibili;
可直接下载three官网:Three.js-VideoTutorial: 本项目是本人three.js视频教程的配套代码以及笔记;
CSDN基础教程:Vue3+ThreeJS的简单使用_vue3 threejs-CSDN博客;
- 总结模型中必要学习的模块及其心得;
2.1必学模块之程序结构:
在使用three去搭建3D模型的时候,我们首先要了解three模型它的构成元素,就像写作文一样,记叙文有时间地点人物三要素,而我们的three模型亦如此;一个基础的three程序结构由场景、相机、渲染器三部分构成,在场景中我们去控制模型和光线;在相机里去操作模块的展示位置和方向;在渲染器里就是创建和渲染;需要了解的如下图展示:(图片借鉴无敌暴龙神)
代码结构为:
2.2必学模块之模型搭建:
模型搭建顾名思义就是在three场景中去建设我们需要的模型;基础图形有点、线、平面、几何体;每个基础图形都有自己的构建方式,而每个模型就像一个对象,搭建的过程就是我们去将对象实例化出来。同样实例化这个对象需要你对三个概念很熟悉,分别是Geometry(几何体)、Material(材料)、Mesh(网格对象);
Geometry描述物体的形状和大小,
Material描述物体的外观和质地,
Mesh则将两者合并在一起,并提供使物体移动,旋转的能力。
案例代码如下:
搭建模型最经常的就是几何体。Three.Js提供了很多现成的几何体,都继承于BufferGeometry对象;关于该对象的教学可以细致的观看CSDN上的知识点:
而在我们的场景中,three 的三角形绘制几何体的方式不太适用,不美观;所以我采用的是提取geometry边界的一个api “EdgesGeometrys”这样就没有多余的三角形线条看起来也舒服。对于模型搭建,在我们关于间隔距离的代码中,有着丰富的案例:
循环遍历生成间隔距离文字:
遍历生成线条:
遍历生成点:
在计算截收面积中有圆形的搭建:
更多模型相关可以去CSDN了解自己操作:
和我一起学 Three.js 【初级篇】:2. 掌握几何体_three.buffergeometry画线-CSDN博客;
-
- 必学模块之重点api和插件
在api这部分,常用和重要的是看项目而言,可能这个项目采用了哪几个那么哪几个就显得很重要;此处介绍CSDN上的一篇博文关于基础api的理解增加印象:
然后再来介绍我们在间隔距离中比较重要的插件:
OrbitControls(轨道控制器)
OrbitControls 是 Three.js 中常用的相机控制器,允许用户通过鼠标或触摸来旋转、平移和缩放相机,以改变观察角度和距离。使用 OrbitControls 可以为用户提供更好的交互体验,并简化相机控制的操作。
DragControls(拖拽控制器)
DragControls 允许用户通过鼠标或触摸来拖拽场景中的物体,实现物体的拖拽和移动功能。通过监听拖拽事件,可以实时获取被拖动物体的位置信息,并实现各种交互效果。在间隔距离中我们有三个api来获取拖拽物体的数据;dragstart、drag、dragend;意思也很明显拖拽前,拖拽中,拖拽后;
然后要注意的是,我们在旋转物体的时候是不可以去拖拽物体上的任意模块;所以我们就要对轨道控制和拖拽控制做出控制;在该功能中,我引入一个变量和方法来控制这两个插件;分别是flagParams和disableDragControls();使用方式如下:
3.难点分析及其解决方式;
3.1在three的三维空间精准的获取鼠标点击对象(也就是每一条网格线线段);
思路:
在根据长宽高和LPS等级生成网格线的时候;在每一条线段里面增加一个keyId;根据这个keyId关键字;通过three的光线投射Raycaster方法去获取鼠标点击的值;与储存的所有网格匹配;得到点击的对象。在我们生成的网格线时,需要将网格线updateMatrixWorld()更新到three对象中去,不然获取不到精准的值。关键代码如下:
3.2拖动网格线;
思路:因为本身存在鼠标的旋转平移事件;所以我们在操作网格线的时候需要现将鼠标旋转平移事件给禁止;然后利用DragControls来拖拽我们选择的网格线;代码如下:
3.3 获取网格线交点:
思路:最终目的还是为了获取网格线交点的数据来作为提交数据;所以采取的方式是全局定义一个变量;在dragstart的时候记录上一次或者第一次拖动物体position;然后在用dragend记录最后位置,利用最后位置减去记录的上一次位置得到diff值,将交点坐标与长度进行修改;