多边形实现三角化

1,194 阅读2分钟

本文基于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…