three.js绘制多边形并更新顶点
先绘制一个正六边形
var geometry = new THREE.Geometry();
let p1 = angPos(r[0], 0);
let p2 = angPos(r[1], 60 * 1);
let p3 = angPos(r[2], 60 * 2);
let p4 = angPos(r[3], 60 * 3);
let p5 = angPos(r[4], 60 * 4);
let p6 = angPos(r[5], 60 * 5);
function angPos(r, ang) {
let _ang = THREE.Math.degToRad(ang);
let x = 3.6 * r * Math.sin(_ang), y = 3.6 * r * Math.cos(_ang);
return [x, y]
}
geometry.vertices.push(
new THREE.Vector3(0, 0, 0),
new THREE.Vector3(p1[0], p1[1], 0),
new THREE.Vector3(p2[0], p2[1], 0),
new THREE.Vector3(p3[0], p3[1], 0),
new THREE.Vector3(p4[0], p4[1], 0),
new THREE.Vector3(p5[0], p5[1], 0),
new THREE.Vector3(p6[0], p6[1], 0),
);
geometry.faces.push(
new THREE.Face3(0, 1, 2),
new THREE.Face3(0, 2, 3),
new THREE.Face3(0, 3, 4),
new THREE.Face3(0, 4, 5),
new THREE.Face3(0, 5, 6),
new THREE.Face3(0, 6, 1),
);
var materiala = new THREE.MeshBasicMaterial({
color: 0x00B2EA,
transparent: true,
opacity: 1.0,
side: THREE.DoubleSide
});
let circle = new THREE.Mesh(geometry, material);
circle.name = "Angle";
scene.add(circle);
然后更新顶点
function runsixAngle(value){
let r = value;
let p1 = angPos(r[0], 0);
let p2 = angPos(r[1], 60 * 1);
let p3 = angPos(r[2], 60 * 2);
let p4 = angPos(r[3], 60 * 3);
let p5 = angPos(r[4], 60 * 4);
let p6 = angPos(r[5], 60 * 5);
function angPos(r, ang) {
let _ang = THREE.Math.degToRad(ang);
let x = 3.6 * r * Math.sin(_ang), y = 3.6 * r * Math.cos(_ang);
return [x, y]
}
let vertices = [];
vertices.push(
new THREE.Vector3(0, 0, 0),
new THREE.Vector3(p1[0], p1[1], 0),
new THREE.Vector3(p2[0], p2[1], 0),
new THREE.Vector3(p3[0], p3[1], 0),
new THREE.Vector3(p4[0], p4[1], 0),
new THREE.Vector3(p5[0], p5[1], 0),
new THREE.Vector3(p6[0], p6[1], 0),
);
let obj = scene.getObjectByName("Angle");
// obj.geometry.vertices = vertices ;
obj.geometry.vertices[2].set(0, 0, 0);
obj.geometry.verticesNeedUpdate = true;
}
采用是Geometry,所以需要通过vertices[i].set
的方式来更新顶点,直接使用等于的方式不行,在bufferGeometry中是可以这样操作的,但是buffer中的顶点坐标非常多,每个三角形都要用三个点来描述,一个三角形3个顶点坐标,而两个三角形需要6个顶点坐标,有两个是重复的。采用Geometry中存储的的是纯顶点坐标,因为有单独的faces数组来存储三角形面的信息。所以你可以根据你的需求使用。
在更新顶点的时候需要设置一下geometry.verticesNeedUpdate = true
,这个很重要。
绘制的多边形长这样
BufferGeometry
Geometry 废弃后 只能BufferGeometry了。
对于过多的顶点可以使用geometry.index属性来共享顶点。
/*
4
0
7 3 1 5
2
6
*/
let i = 0;
const geometry = new THREE.BufferGeometry();
const verticesarr = new Float32Array([
0, 0.2, 0,
0.2, 0, 0,
0, -0.2, 0,
-0.2, 0, 0,
0, 1, 0,
1, 0, 0,
0, -1, 0,
-1, 0, 0,
]);
const geometryaee = new THREE.BufferAttribute(verticesarr, 3);
geometry.setAttribute('position', geometryaee);
geometry.index = new THREE.BufferAttribute(new Uint16Array([
3, 4, 1,
1, 6, 3,
0, 5, 2,
2, 7, 0
]), 1);
const material = new THREE.MeshBasicMaterial({
color: 0xffffff,
side: THREE.DoubleSide,
wireframe: true,
});
const mesh = new THREE.Mesh(geometry, material);
this.scene.add(mesh);
setInterval(() => {
i += 0.15;
verticesarr[3 * 4 + 1] = 1 + 0.25 * (Math.sin(i) + Math.sin(i / 10));
verticesarr[3 * 6 + 1] = -1 - 0.25 * (Math.sin(i) + Math.sin(i / 10));
verticesarr[3 * 5 + 0] = 1 + 0.25 * Math.cos(i);
verticesarr[3 * 7 + 0] = -1 - 0.25 * Math.cos(i);
geometryaee.needsUpdate = true;
}, 100);
长度变化的小星星。
加一个plane
const planeGeometry = new THREE.PlaneBufferGeometry(1, 1, 1);
const planeMaterial = new THREE.MeshBasicMaterial({
color: 0xffffff,
side: THREE.DoubleSide,
});
const plane = new THREE.Mesh(planeGeometry, planeMaterial);
plane.rotation.z = Math.PI / 4;
this.scene.add(plane);
const Pi4 = Math.PI / 4;
const vertices: any = planeGeometry.attributes.position.array;
let i = 0, k = 0;
setInterval(() => {
i += 0.04;
k = 0.5 * Math.abs(Math.cos(i));
vertices[0] = -(k) * (Math.sin(3 * Pi4));
vertices[1] = -(k) * (Math.cos(3 * Pi4));
vertices[9] = (k) * Math.sin(3 * Pi4);
vertices[10] = (k) * Math.cos(3 * Pi4);
planeGeometry.attributes.position.needsUpdate = true;
}, 100);