我想在three.js地球仪上模拟由风驱动的粒子。我拥有的数据是一个用于粒子位置的Vector3和一个指示风速和方向的Vector2,想想北/东。我如何获得新的Vector3?
我已经查阅了大量示例并阅读了文档,并认为解决方案涉及四元数,但未给出旋转轴。此外,有数以千计的粒子,它应该很快,但不需要实时。
球体的半径为1.
答案 0 :(得分:1)
我建议您查看three.js提供的Spherical
类。而不是笛卡尔坐标(x,y,z),用spherical coordinate-system(θ(θ),φ(phi),r)来表示一个点。
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轴开始,然后转向'最终走向风的方向,没有任何向量的旋转。它有一个质量,一个方向的速度,一个力作用在它上面,它转动。
你可以看到,因为整个速度受到摩擦(multscalar),我们的初始速度随着风向量的累积而减小,这导致转弯而不进行任何旋转。我想把它扔掉,以防万一你不熟悉使用粒子系统而且可能只是想错了。