import * as THREE from 'three'; class HexNutGeometry extends THREE.BufferGeometry { constructor(radius = 1, height = 0.5, holeRadius = 0.6) { super(); this.parameters = { radius: radius, height: height, holeRadius: holeRadius }; this.buildGeometry(); } buildGeometry() { const radius = this.parameters.radius; const height = this.parameters.height; const holeRadius = this.parameters.holeRadius; const vertices = []; const indices = []; // 1. 定义六边形的顶点 (顶部和底部) for (let i = 0; i < 6; i++) { const angle = (Math.PI * 2 / 6) * i; const x = radius * Math.cos(angle); const y = radius * Math.sin(angle); // 顶部顶点 vertices.push(x, y, height / 2); // 底部顶点 vertices.push(x, y, -height / 2); } // 内部孔洞的顶点 (顶部和底部) for (let i = 0; i < 32; i++) { // 使用更多分段来近似圆形 const angle = (Math.PI * 2 / 32) * i; const x = holeRadius * Math.cos(angle); const y = holeRadius * Math.sin(angle); // 顶部内侧顶点 vertices.push(x, y, height / 2); // 索引从 12 开始 // 底部内侧顶点 vertices.push(x, y, -height / 2); // 索引从 12 + 32 开始 } // 2. 定义侧面 for (let i = 0; i < 6; i++) { const currentTop = i * 2; const nextTop = ((i + 1) % 6) * 2; const currentBottom = i * 2 + 1; const nextBottom = ((i + 1) % 6) * 2 + 1; // 两个三角形组成一个侧面 indices.push(currentTop, nextTop, currentBottom); indices.push(nextTop, nextBottom, currentBottom); } // 3. 定义顶部和底部 (六边形扇面 - 注意避开中心孔洞) // 顶部 for (let i = 0; i < 6; i++) { const current = i * 2; const next = ((i + 1) % 6) * 2; // 使用孔洞边缘的顶点来创建顶部面 const holeIndex1 = 12 + i * 2; const holeIndex2 = 12 + ((i + 1) % 32) * 2; // 注意孔洞分段数 indices.push(current, next, holeIndex1); indices.push(next, holeIndex2, holeIndex1); } // 底部 for (let i = 0; i < 6; i++) { const current = i * 2 + 1; const next = ((i + 1) % 6) * 2 + 1; // 使用孔洞边缘的顶点来创建底面 const holeIndex1 = 12 + 64 + i * 2; const holeIndex2 = 12 + 64 + ((i + 1) % 32) * 2; // 注意孔洞分段数 indices.push(current, holeIndex1, next); indices.push(holeIndex1, holeIndex2, next); } // 4. 定义内部孔洞的侧面 for (let i = 0; i < 32; i++) { const currentTop = 12 + i * 2; const nextTop = 12 + ((i + 1) % 32) * 2; const currentBottom = 12 + 64 + i * 2; const nextBottom = 12 + 64 + ((i + 1) % 32) * 2; indices.push(currentTop, nextTop, currentBottom); indices.push(nextTop, nextBottom, currentBottom); } this.setAttribute('position', new THREE.Float32BufferAttribute(vertices, 3)); this.setIndex(indices); this.computeVertexNormals(); } } export { HexNutGeometry };