头像

zjian

Just Code!

帖子照片墙关于

几何体根据任意点旋转

2024-06-01 01:46

最近做项目的时候遇到了一个问题,就是THREE的几何体旋转是以物体的坐标原点作为旋转点旋转的。 这里物体坐标原点,实际就是物体的position坐标,不是世界坐标原点。

这边有个需求,需要把物体根据任意的点作为坐标原点旋转。

目前研究出来一般有两种方法。
第一种: 在物体外面套一层group, 然后, 设置物体的坐标改为相对于group的坐标。然后把旋转点作为group的position, 这样让group旋转,物体也就自然跟着旋转了。对于任意给定的点,让group移动到对应点即可。

但这样的实现太过ugly, 根本无法忍受!

于是还有另一种方法,这个方法分为三步:

  1. 第一步, 移动物体到旋转点
  2. 第二步, 以自身的坐标原点旋转。
  3. 最后再移动回去。

这里一个问题,第一步是把物体移动到旋转点,最后一步又是移动回去,这样不是相当于没移动么,还是按自身坐标原点旋转呀?
答案是最后一步, 最后一步因为经过了自身的旋转,所以它的xyz轴的方向都变化了,这个时候恢复,自然也就不会是一开始的点了。

具体的效果:
原始:
1717177342471.png
旋转后(沿着y轴旋转90度):
1717177235865.png

具体代码:

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);