代码出处: // https://github.com/pailhead/three-rounded-box
球几何体(1)-制作1/8圆
本小结效果:
1、球坐标系
https://blog.csdn.net/qq_35097289/article/details/94003524
球坐标中是这样表示空间中一点的:
- 用ρ表示点到原点的距离,0 ≤ ρ≤ +∞;
- 在ρz平面上,从z轴正半轴向ρ偏转的角度是φ,0 ≤ φ≤ π;
- 从x轴偏转到平面的角度是θ,0 ≤ θ≤ 2π,如下图所示:
2、1/8圆的顶点坐标
对于半径为1的圆。
// 垂直角度
var va = v * PIhalf;
// 水平角度
var ha = u * PIhalf;
vertex.x = Math.cos(va) * Math.cos(ha);
vertex.y = Math.sin(va);
vertex.z = Math.cos(va) * Math.sin(ha);
3、顶点坐标实例
分1段:
// 顶点坐标
position.arr = [
1, 0, 0,
0, 0, 1,
0, 1, 0,
]
// 三角形面的索引
indices = [
0, 2, 1
]
分2段:
arr = [
1, 0, 0, 【0】
0.71, 0, 0.71, 【1】
0, 0, 1, 【2】
0.71, 0.71, 0, 【3】
0.5, 0.71, 0.5, 【4】
0, 0.71, 0.71, 【5】
0, 1, 0, 【6】
]
indices = [
0, 3, 1,
1, 3, 4,
1, 4, 2,
2, 4, 5,
3, 6, 4,
4, 6, 5
]
分3段:
4、部分代码
// 获取顶点
getVer() {
let vertex = new THREE.Vector3()
const radius = 1
const { radiusSegments } = this.parameters
var PIhalf = Math.PI / 2;
let vertexPool = []
// 每次循环产生一行的顶点
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, 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;
//make 1/8 sphere points
vertex.x = cosVa * Math.cos( ha );
vertex.y = sinVa;
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
}
// 构造面的顶点索引
doCorners() {
const { radiusSegments } = this.parameters
const { rs1 ,indices,lastVertex} = this
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 = r1 + u;
var b = r1 + u1;
var c = r2 + u;
var d = 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 = lastRowOffset + u;
var b = lastRowOffset + u + 1;
var c = lastVertex;
indices.push( a );
indices.push( c );
indices.push( b );
}
}