本文基于javascript语言,但实现多边形三角化的原理是一样的。
有时候我们画一个三维几何体, 几何体是由许多面拼凑在一起的,每个面又是由许多三角形拼凑在一起的。webgl绘制每个面,都是使用的三角扇去绘制,比如下面的OBJ文件里面给出的顶点索引是:
f 1 2 3 4 5
这时候使用三角扇去绘制,三个顶点索引构成一个三角形,我们需要转换成:
1 2 3
1 3 4
1 4 5
但遇到不规则的面比如下面这种,就会出现问题:
这时候就不能用三角扇去绘制几何体的不规则面,这里是判断f里面有n个顶点索引,如果n - 2 > 4,则需要进行三角化。
三角化的步骤为:
1、找到需要三角化的面里面的任意两个顶点相减求出它们的向量。(点是随便写的)
var p0 = new THREE.Vector3( 1, 2, 3 );
var p1 = new THREE.Vector3( 4, 5, 6 );
var yVec= p1.clone().sub( p0 ).normalize();
2、通过已求出的向量,叉乘该面的法线,则求出另一条向量。
var xVec = yVec.clone().cross( nVec );
3、通过该面已知的两条向量,组合成全局坐标系到面坐标系的一个转换矩阵
var m = new THREE.Matrix3();
m.set(
xVec.x, xVec.y, xVec.z,
yVec.x, yVec.y, yVec.z,
nVec.x, nVec.y, nVec.z
)
4、有了这个转换矩阵,将该面里面的所有顶点都与这个矩阵相乘,算出投影后的顶点坐标
var point = new THREE.Vector3( 1, 2, 3 );
point.applyMatrix3( m );
5、拿到转换后的顶点坐标,因为是降维到平面,所以只需要拿三维坐标里面的x、y值即可
earcutData.push( point.x, point.y );
6、然后再把平面顶点进行耳切法,算出的顶点索引就是我们需要实现的三角化功能
earcutData = Earcut.triangulate( earcutData );
最后效果如下:
耳切法需要安装的依赖:github.com/mrdoob/thre…