THREE.JS 创建空心圆环

实际效果

 

 


可根据条件自行优化

class CircleData { constructor({radius, segments, thetaStart, thetaLength, color, height, LineColor}) { radius
= radius || 1 segments = segments !== undefined ? Math.max(3, segments) : 8; thetaStart = thetaStart !== undefined ? thetaStart : 0; console.log(thetaLength); thetaLength = thetaLength !== undefined ? thetaLength : Math.PI; color = color? color: '#ff0000'; LineColor = LineColor? LineColor: '#fff'; height = height? height: .5; const InnerCircleRadius = 1.5 // 内部圆占的比列 const material = new THREE.MeshBasicMaterial( { color: color, opacity: .5, side: THREE.DoubleSide, transparent: true } ); //顶点索引 let indices = []; // 顶点坐标 let vertices = []; const zPos = height; let i, s; let vertex = new THREE.Vector3(); let group = new THREE.Group(); scene.add(group); // vertices.push(0, 0, 0); let botllx = []; let toppoint = []; let rightSide = []; let leftSide = []; // 生成顶点 for(let s = 0, i = 3; s <= segments; s++, i+= 3) { var segment = thetaStart + s / segments * thetaLength; vertex.x = radius * Math.cos(segment); vertex.y = radius * Math.sin(segment); vertices.push(vertex.x, vertex.y, vertex.z); botllx.push(vertex.x, vertex.y, vertex.z); rightSide.push(vertex.x, vertex.y, vertex.z); vertex.x = radius / InnerCircleRadius * Math.cos(segment); vertex.y = radius / InnerCircleRadius * Math.sin(segment); vertices.push(vertex.x, vertex.y, vertex.z); toppoint.push(vertex.x, vertex.y, vertex.z); leftSide.push(vertex.x, vertex.y, vertex.z); vertex.x = radius * Math.cos(segment); vertex.y = radius * Math.sin(segment); rightSide.push(vertex.x, vertex.y, zPos); vertex.x = radius / InnerCircleRadius * Math.cos(segment); vertex.y = radius / InnerCircleRadius * Math.sin(segment); leftSide.push(vertex.x, vertex.y, zPos); } for (i = 0; i <= segments * 2; i++) { if(i %2 == 0) { indices.push(i+2, i + 1, i); } else { indices.push(i, i + 1, i+2); } } // 线1 const material2 = new THREE.LineBasicMaterial( { color: LineColor, opacity: .9,transparent: true} ); const geometry2 = new THREE.BufferGeometry(); const vertices2 = new Float32Array(botllx); geometry2.setAttribute( 'position', new THREE.BufferAttribute( vertices2, 3 ) ); let line = new THREE.Line( geometry2, material2 ); group.add(line); // 线2 const geometry4 = new THREE.BufferGeometry(); const vertices4 = new Float32Array(toppoint); geometry4.setAttribute( 'position', new THREE.BufferAttribute( vertices4, 3 ) ); let line2 = new THREE.Line( geometry4, material2 ); group.add(line2); // 复制线 let lien3 = line.clone(); lien3.position.z = zPos; group.add(lien3); let lien4 = line2.clone(); lien4.position.z = zPos; group.add(lien4); // 左边的线 const geometrySide = new THREE.BufferGeometry(); let vertexbotllx = [toppoint[0], toppoint[1], toppoint[2]]; vertexbotllx = [...vertexbotllx, ...[botllx[0], botllx[1], botllx[2]]] vertexbotllx = [...vertexbotllx, ...[botllx[0], botllx[1], zPos]] vertexbotllx = [...vertexbotllx, ...[toppoint[0], toppoint[1], zPos]] vertexbotllx = [...vertexbotllx, ...[toppoint[0], toppoint[1],botllx[2]]] const verticesSide = new Float32Array(vertexbotllx); geometrySide.setAttribute( 'position', new THREE.BufferAttribute( verticesSide, 3 ) ); let line2Side = new THREE.Line( geometrySide, material2 ); group.add(line2Side); // 左边的面 const geometryLeftSide = new THREE.BufferGeometry(); const verticesLeftSide = new Float32Array(vertexbotllx); geometryLeftSide.setIndex([2, 1, 0, 3, 2, 0]) geometryLeftSide.setAttribute( 'position', new THREE.BufferAttribute( verticesLeftSide, 3 ) ); const meshLeftSide = new THREE.Mesh( geometryLeftSide, material ); meshLeftSide.name = ''; group.add(meshLeftSide); // 和右边的线 let leftLinePoint = [radius * Math.cos(segment), radius * Math.sin(segment), 0, radius / InnerCircleRadius * Math.cos(segment), radius / InnerCircleRadius * Math.sin(segment), 0]; const geometrySide2 = new THREE.BufferGeometry(); let vertexbotllx2 = [...leftLinePoint]; vertexbotllx2 = [...vertexbotllx2, leftLinePoint[3], leftLinePoint[4], zPos] vertexbotllx2 = [...vertexbotllx2, leftLinePoint[0], leftLinePoint[1], zPos] vertexbotllx2 = [...vertexbotllx2, leftLinePoint[0], leftLinePoint[1], 0] const verticesSide2 = new Float32Array(vertexbotllx2); geometrySide2.setAttribute( 'position', new THREE.BufferAttribute( verticesSide2, 3 ) ); let line2Side2 = new THREE.Line( geometrySide2, material2 ); group.add(line2Side2); const geometryRightSide = new THREE.BufferGeometry(); const verticesRightSide = new Float32Array(vertexbotllx2); geometryRightSide.setIndex([2, 1, 0, 3, 2, 0]) geometryRightSide.setAttribute( 'position', new THREE.BufferAttribute( verticesRightSide, 3 ) ); const meshRightSide = new THREE.Mesh( geometryRightSide, material ); group.add(meshRightSide); // 生成形状 const geometry = new THREE.BufferGeometry(); const vertices3 = new Float32Array(vertices); geometry.setIndex(indices) geometry.setAttribute( 'position', new THREE.BufferAttribute( vertices3, 3 ) ); const mesh = new THREE.Mesh( geometry, material ); mesh.name = ''; group.add(mesh); let mesh2 = mesh.clone(); mesh2.name = '1'; mesh2.position.z = zPos; group.add(mesh2); // 生成侧边数据 const leftGeometry = new THREE.BufferGeometry(); const leftVertices = new Float32Array(leftSide); indices = indices.splice(0, indices.length - 3); leftGeometry.setIndex(indices) leftGeometry.setAttribute( 'position', new THREE.BufferAttribute( leftVertices, 3 ) ); const leftMesh = new THREE.Mesh( leftGeometry, material ); leftMesh.name = ''; group.add(leftMesh); const RightGeometry = new THREE.BufferGeometry(); const RightVertices = new Float32Array(rightSide); RightGeometry.setIndex(indices) RightGeometry.setAttribute( 'position', new THREE.BufferAttribute( RightVertices, 3 ) ); const RightMesh = new THREE.Mesh( RightGeometry, material ); RightMesh.name = ''; group.add(RightMesh); group.rotation.x = -Math.PI / 3; return group; } }

 

posted @ 2022-12-23 16:21  大帅比2  阅读(322)  评论(0编辑  收藏  举报