如何使用Vector2旋转Vector3?

时间:2017-05-21 15:38:28

标签: vector three.js

我想在three.js地球仪上模拟由风驱动的粒子。我拥有的数据是一个用于粒子位置的Vector3和一个指示风速和方向的Vector2,想想北/东。我如何获得新的Vector3?

我已经查阅了大量示例并阅读了文档,并认为解决方案涉及四元数,但未给出旋转轴。此外,有数以千计的粒子,它应该很快,但不需要实时。

球体的半径为1.

2 个答案:

答案 0 :(得分:1)

我建议您查看three.js提供的Spherical类。而不是笛卡尔坐标(x,y,z),用spherical coordinate-system(θ(θ),φ(phi),r)来表示一个点。

spherical coordinate system

theta的值是经度,phi是地球的纬度(r - sphereRadius将是地球表面的高度)。然后,您的风矢量可以解释为对这两个值的更改。所以我会尝试的基本上是这样的:

// a) convert particle-location to spherical
const sphericalPosition = new THREE.Spherical()
    .setFromVector3(particle.position);

// b) update theta/phi (note that windSpeed is assumed to 
//    be given in radians/time, but for a sphere of size 1 that 
//    shouldn't make a difference)
sphericalPosition.theta += windSpeed.x; // east-direction
sphericalPosition.phi += windSpeed.y; // north-direction

// c) write back to particle-position
particle.position.setFromSpherical(sphericalPosition);

性能明智这根本不应该是一个问题(也许不要像我上面那样为每个粒子创建一个新的Spherical实例)。转换涉及一些三角函数,但我们只谈了数千个点,而不是数百万个。

希望有所帮助!

答案 1 :(得分:0)

如果您只想基于角度旋转矢量,只需使用trig as per this page在指定平面上执行简单的值旋转,例如在xz平面上旋转:

var x = cos(theta)*vec_to_rotate.x - sin(theta)*vec_to_rotate.z;
var z = sin(theta)*vec_to_rotate.x + cos(theta)*vec_to_rotate.z;
rotated_vector = new THREE.Vector3(x,vec_to_rotate.y,z);

但是要用风移动粒子,你并没有真正旋转一个向量,你应该添加一个速度向量,并且它会旋转'基于初始速度,惯性,空气摩擦和其他竞争力的组合,它自己的方向是:

init(){
    position = new THREE.Vector(0,0,0);
    velocity = new THREE.Vector3(1,0,0);
    wind_vector = new THREE.Vector3(0,0,1);
}

update(){
    velocity.add(wind_vector);
    position.add(velocity);
    velocity.multiplyScalar(.95);
}

这个模型更真实地说明风将如何影响粒子。这个粒子将沿着x轴开始,然后转向'最终走向风的方向,没有任何向量的旋转。它有一个质量,一个方向的速度,一个力作用在它上面,它转动。

enter image description here

你可以看到,因为整个速度受到摩擦(multscalar),我们的初始速度随着风向量的累积而减小,这导致转弯而不进行任何旋转。我想把它扔掉,以防万一你不熟悉使用粒子系统而且可能只是想错了。