几何体根据任意点旋转
2024-06-01 01:46
最近做项目的时候遇到了一个问题,就是THREE的几何体旋转是以物体的坐标原点作为旋转点旋转的。 这里物体坐标原点,实际就是物体的position坐标,不是世界坐标原点。
这边有个需求,需要把物体根据任意的点作为坐标原点旋转。
目前研究出来一般有两种方法。
第一种: 在物体外面套一层group, 然后, 设置物体的坐标改为相对于group的坐标。然后把旋转点作为group的position, 这样让group旋转,物体也就自然跟着旋转了。对于任意给定的点,让group移动到对应点即可。
但这样的实现太过ugly, 根本无法忍受!
于是还有另一种方法,这个方法分为三步:
- 第一步, 移动物体到旋转点
- 第二步, 以自身的坐标原点旋转。
- 最后再移动回去。
这里一个问题,第一步是把物体移动到旋转点,最后一步又是移动回去,这样不是相当于没移动么,还是按自身坐标原点旋转呀?
答案是最后一步, 最后一步因为经过了自身的旋转,所以它的xyz轴的方向都变化了,这个时候恢复,自然也就不会是一开始的点了。
具体的效果:
原始:
旋转后(沿着y轴旋转90度):
具体代码:
import * as THREE from 'three';
import { scene } from './framework';
function getBox(x: number = 4, y:number = 4, z:number = 4) {
const geometry = new THREE.BoxGeometry(x, y, z);
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
const cube = new THREE.Mesh(geometry, material);
return cube;
}
const box1 = getBox();
box1.position.set(10, 0, 0);
scene.add(box1);
const box2 = getBox(4, 4, 2);
box2.position.set(30, 0, 0);
// 算出旋转点到原点的向量
const vect = box2.position.clone().sub(box1.position);
// 移动到旋转点
box2.position.set(box1.position.x, box1.position.y, box1.position.z);
// 执行旋转 这里绕y轴旋转90度
box2.setRotationFromEuler(new THREE.Euler(0, Math.PI / 2, 0));
// 这里沿向量移动回去
box2.translateOnAxis(vect.clone().normalize(), vect.length());
scene.add(box2);