球几何体(2)-构造完整球
接上一篇,球几何体(1)-制作1/8圆
最终效果:
将其他1/8圆补全即可。
export default class SphereGeometry extends THREE.BufferGeometry {
constructor(radius,) {
super()
window.lm = this
this.parameters = {
radiusSegments: 10
}
this.indices = []
this.rs1 = this.parameters.radiusSegments + 1
this.cornerVertNumber = this.rs1 * this.parameters.radiusSegments + 1
this.lastVertex = this.rs1 * this.parameters.radiusSegments
this.totalVertexCount = (this.rs1 * this.parameters.radiusSegments + 1) << 3;
let positions = new THREE.BufferAttribute( new Float32Array( this.totalVertexCount * 3 ), 3 );
this.vertexPool = []
// [0~-90],[90~180],[180~270],[270~360]
this.getVer({yy:1,ii:0})
this.doCorners(0)
this.getVer({yy:1,ii:1})
this.doCorners(1)
this.getVer({yy:1,ii:2})
this.doCorners(2)
this.getVer({yy:1,ii:3})
this.doCorners(3)
this.getVer({yy:-1,ii:0})
this.doCorners(4)
this.getVer({yy:-1,ii:1})
this.doCorners(5)
this.getVer({yy:-1,ii:2})
this.doCorners(6)
this.getVer({yy:-1,ii:3})
this.doCorners(7)
// this.vertexPool = vertexPool
for (var i = 0; i < this.vertexPool.length; i++){
positions.setXYZ(
i,
this.vertexPool[i].x ,
this.vertexPool[i].y ,
this.vertexPool[i].z
);
}
this.setIndex(new THREE.BufferAttribute(new Uint16Array(this.indices), 1));
this.setAttribute('position', positions);
}
doCorners(i) {
const { radiusSegments } = this.parameters
const { rs1 ,indices,lastVertex} = this
var cornerOffset = this.cornerVertNumber * i;
var lastRowOffset = rs1 * ( radiusSegments - 1 );
// 每次循环产生一行的顶点索引
for (var v = 0; v < radiusSegments - 1; v++){
var r1 = v * rs1; //row offset
var r2 = (v + 1) * rs1; //next row
// 每次循环产生2个三角形,6个顶点索引
for (var u = 0; u < radiusSegments; u++){
var u1 = u + 1;
var a = cornerOffset+r1 + u;
var b = cornerOffset+r1 + u1;
var c = cornerOffset+r2 + u;
var d = cornerOffset+r2 + u1;
// console.error(a);
indices.push( a );
indices.push( c );
indices.push( b );
indices.push( b );
indices.push( c );
indices.push(d);
}
}
// 最后最上面一行的三角形
for (var u = 0; u < radiusSegments; u++){
// console.error(89);
var a = cornerOffset+lastRowOffset + u;
var b = cornerOffset+lastRowOffset + u + 1;
var c = cornerOffset+lastVertex;
indices.push( a );
indices.push( c );
indices.push( b );
}
}
getVer({yy,ii}) {
let vertex = new THREE.Vector3()
const radius = 1
const { radiusSegments } = this.parameters
var PIhalf = Math.PI / 2;
let { vertexPool } = this
// 每次循环产生一行的顶点
for (var y = 0; y <= radiusSegments; y++) {
var v = y / radiusSegments;
// φ
var va = v * PIhalf; //arrange in 90 deg
var cosVa = Math.cos(va); //scale of vertical angle
var sinVa = Math.sin(va);
// 最后一个点
if (y == radiusSegments) {
vertex.set(0, 1*yy, 0);
var vert = vertex.clone().multiplyScalar(radius)
vertexPool.push( vert );
continue; //skip row loop
}
// 每次循环产生一个顶点
for (var x = 0; x <= radiusSegments; x++) {
// θ
var u = x / radiusSegments;
var ha = u * PIhalf + ii * PIhalf;
//make 1/8 sphere points
vertex.x = cosVa * Math.cos( ha );
vertex.y = sinVa*yy;
vertex.z = cosVa * Math.sin(ha);
vertex.x = +vertex.x.toFixed(2)
vertex.y = +vertex.y.toFixed(2)
vertex.z = +vertex.z.toFixed(2)
var vert = vertex.clone()
vertexPool.push( vert );
}
}
return vertexPool
}
}