javascript - 如何使用 Three.js 定义相对于矢量路径的粒子云?

标签 javascript vector graphics three.js particle-system

我一直在研究和使用 Three.js 中的粒子云示例。大多数使用形状几何形状来定义粒子场,或将粒子随机分布在整个视场中的参数。我想做的是创建一个粒子云,其中每个粒子都相对接近不可见的矢量路径。例如,如果我定义了一条轻微弯曲的矢量路径,则所有粒子都可能沿着不可见的一致半径 float ,然后可能向末端逐渐变细,形成热狗形状的粒子云。那么,我知道如何创建粒子,也知道如何创建矢量路径,如何将这两个东西链接在一起?谢谢!

最佳答案

您可以使用两个点定义路径。令这些点为pqv = 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 。因此,我们只需要生成lambdamu一切都准备好了。

注意:lambdamu必须是区间 [-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/

相关文章:

javascript - 手机上的 Google Plus1。 - 如何禁用注释

javascript - 我可以在没有 HTML 的浏览器中运行 JavaScript 吗?为什么/为什么不?

javascript - 如何恢复根据从 Firebase 获取的数字生成的列表的顺序?

c++ - C++ 中 std::vector 的基本问题

java 图形 paintComponent

javascript - Jquery - 缓慢加载页面并具有加载gif效果

c++ - 带 std::vector 的 XTEA 函数

c++ - 如何在 C++ 中将 vector<int> 连接到单个 int?

Android - 如何使用自定义 SurfaceView 为移动形状制作动画?

android - 在 Android 中绘制单杠最简单的方法是什么?