如何在Three.js中通过Vector3数组绘制并挤出3D对象
基于Vector3数组实现三维多边形挤出的实现方案
所有传入的Vector3点位必须共面,且按统一的顺时针/逆时针顺序排列、无点位交叉,否则无法生成合法的闭合填充面,这是多边形挤出的前置要求。
你原本用Shape+ExtrudeGeometry的实现思路完全可行,只需要补充3D坐标到2D平面的转换逻辑即可,也可以选择跳过Shape直接自定义构建几何体,两种方案具体实现逻辑如下:
方案一:适配原有Shape+ExtrudeGeometry逻辑
Shape仅支持Vector2参数的限制,可以通过局部平面投影转换绕过:
- 第一步:构建3D平面的本地2D坐标系
从点位中取3个不共线的点计算出平面法向量,再基于法向量推导两个落在平面内、互相垂直的单位正交基向量u、v,相当于给倾斜的3D平面建立一套本地二维坐标体系,取点集中任意一个点作为坐标原点。 - 第二步:Vector3转本地Vector2生成Shape
对每个3D点位,减去本地原点得到相对位置向量,将向量分别和u、v做点积,得到的两个数值就是对应本地二维坐标的x、y分量,把所有转换后的Vector2按顺序传入Shape即可生成合法的闭合轮廓。 - 第三步:对齐挤出几何体到3D空间
用生成的Shape调用ExtrudeGeometry得到的几何体默认落在XY平面,给几何体应用变换矩阵,将默认XY平面对齐到原3D点位所在平面即可,核心变换参考代码:// normal为平面单位法向量,u、v为平面内正交单位基向量,origin为选定的平面本地原点 const alignMatrix = new THREE.Matrix4().set( u.x, v.x, normal.x, origin.x, u.y, v.y, normal.y, origin.y, u.z, v.z, normal.z, origin.z, 0, 0, 0, 1 ); extrudeGeometry.applyMatrix4(alignMatrix);
方案二:直接基于3D点构建挤出几何体
如果不想做坐标投影转换,可以直接按点位生成轮廓、填充后挤出:
- 第一步:生成三维轮廓线
按传入的点序把所有Vector3点位依次连接、首尾闭合,调用LineLoop即可直接生成三维空间的轮廓线效果。 - 第二步:填充轮廓面
对共面的闭合点集做三角剖分(Three.js内置了对应三角剖分工具方法),把轮廓围成的区域拆分为若干三角面,生成底面/顶面的顶点与索引数据。 - 第三步:生成挤出侧面
沿着平面法向量方向,把所有轮廓点偏移设定的挤出厚度,得到另一层的顶面/底面顶点,将两层顶点按顺序两两连接,生成侧面的三角面数据,把所有三角面的顶点、索引、uv数据合并为BufferGeometry,即可得到完整的三维挤出多边形。
注意:如果点位顺序混乱、存在交叉,会直接导致填充面翻转、扭曲,挤出结果异常,传入点集前需要先校验点序合法性。
内容的提问来源于stack exchange,提问作者Ferdi
相关产品推荐
相关产品推荐

