Three.js 中的源码, https://github.com/mrdoob/three.js/blob/master/src/geometries/TetrahedronGeometry.js
function TetrahedronGeometry( radius, detail ) {
Geometry.call( this );
this.type = 'TetrahedronGeometry';
this.parameters = {
radius: radius,
detail: detail
};
this.fromBufferGeometry( new TetrahedronBufferGeometry( radius, detail ) );
this.mergeVertices();
}
这里 radius 定义的是 正四面几何体的外接球半径,detail 参数比较费解,必须看源码才能弄清,
detail 的默认值是0,相关代码在 three.js 的 PolyhedronBufferGeometry() 函数中,
function PolyhedronBufferGeometry( vertices, indices, radius, detail )
PolyhedronBufferGeometry 中的 subdivide() 函数 专门为处理这个 detail,最关键的代码在subdivideFace 函数,
为了看懂代码,首先从github上拉下three.js master 分支的代码,chrome或firefox 中打开文件 three.js-master/docs/scenes/geometry-browser.html,然后重新修改页面地址为
http://localhost:63343/three.js-master/docs/scenes/geometry-browser.html?_ijt=sf0c7m1cpjh4mb0369cn33ns65#TetrahedronGeometry
然后在subdivideFace的函数体中打断点,把页面中的detail 从零改为1, 然后就会项目就会运行到断点处,由于函数
function subdivideFace( a, b, c, detail )
对于subdivideFace函数,现在它的每个参数都有具体的,简单的值,这种情况利于分析代码,经过分析,当detail = 1 时,
这个函数会对 a,b,c三个点确定三角形,每条边都插入一个中点,然后就有六个点了;a,b,c 三个顶点再分别和其两条邻边的中点组合成三个 三角形, 三条边的中点再组合为一个三角形,这样一个三角形就被其三条中位线切成4个小三角形了。
同理,容易得出,当detail = 2 时,一个三角形 会被切成 16 个小三角形,这里其实隐含一个递归,虽然代码不是直接递归的。
这些小三角形的顶点都会以数组形式,存到PolyhedronBufferGeometry的vertexBuffer变量中,然后调用PolyhedronBufferGeometry 的 appplyRadius函数,会根据之前那个外接球半径参数,分别把这些顶点投射到外接球的球面上,投射指的是从原点到顶点做一条射线,射线和外接球的球面的交点,就是投射后的点。外接球的球心也是原点(0,0,0)
把detail 逐步调整大,可以看到,球面的点的密度是不同的,正四面体最初的四个顶点的周围的点密度最大。
PolyhedronBufferGeometry.azimuth( vector ) 顺着Y轴的负方向看, 以逆时针旋转方向为正,从X轴负方向,旋转到vector在xz平面的投影所需角度
PolyhedronBufferGeometry.inclination( vector ) 返回vector 和xz平面的线面角