实际效果
![]()
可根据条件自行优化
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;
}
}