我一直在研究和使用 Three.js 中的粒子云示例。大多数使用形状几何形状来定义粒子场,或将粒子随机分布在整个视场中的参数。我想做的是创建一个粒子云,其中每个粒子都相对接近不可见的矢量路径。例如,如果我定义了一条轻微弯曲的矢量路径,则所有粒子都可能沿着不可见的一致半径 float ,然后可能向末端逐渐变细,形成热狗形状的粒子云。那么,我知道如何创建粒子,也知道如何创建矢量路径,如何将这两个东西链接在一起?谢谢!
最佳答案
您可以使用两个点定义路径。令这些点为p
和q
让v = p - q
。任意点M
位于路径上必须满足向量方程
M = (1 - lambda) * p + lambda * q
对于一些0 <= lambda <= 1
。因此,您可以通过生成随机lambda
来生成路径上的随机点。并在上面的等式中使用它的值:
// p and q are instances of THREE.Vector3
function pointOnPath(p, q) {
var lambda = Math.random();
var scaledp = (new THREE.Vector3()).copy(p).multiplyScalar(1 - lambda);
var scaleq = (new THREE.Vector3()).copy(q).multiplyScalar(lambda);
var result = (new THREE.Vector3()).addVectors(scaledp, scaledq);
return result;
}
接下来,您想要用一些小半径修改计算出的坐标,以便它们围绕路径旋转。您可以通过添加一个小的矢量偏移来实现这一点。那么我们如何计算该向量呢?
我们要寻找的向量位于垂直于 p
的线的平面上。至q
。满足上述条件的向量有无数个,其中两个是 e1 = (v.y, -v.x, 0)
和e2 = (v.z, 0, -v.x)
。 lambda * e1 + mu * e2
形式的任何向量也将垂直于 v
。因此,我们只需要生成lambda
和mu
一切都准备好了。
注意:lambda
和mu
必须是区间 [-1; 内的随机数; 1],而不是[0; 1]。由于我们正在标准化 offset
向量,区间[-0.5; 0.5] 就足够了,因为标准化会将其映射到 [-1; 1]
function getVectorOffset(p, q, radius) {
var v = (new THREE.Vector3()).subVectors(q, p);
v.normalize();
var e1 = new THREE.Vector3(v.y, -v.x, 0),
e2 = new THREE.Vector3(v.z, 0, -v.x);
e1.normalize();
e2.normalize();
var lambda = Math.random() - 0.5,
mu = Math.random() - 0.5;
var offset = e1.multiplyScalar(lambda).add(e2.multiplyScalar(mu));
offset.normalize();
offset.multiplyScalar(radius) // multiply the compute offset by the radius you'd like it to circle around
return offset;
}
最后,生成您想要的点:
function pointOnHotDog(p, q, radius) {
return pointOnPath(p, q).add(getVectorOffset(p, q, radius));
}
这是一个工作 jsfiddle
关于javascript - 如何使用 Three.js 定义相对于矢量路径的粒子云?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24784413/