1

画面全体に数千の粒子が散らばっている ParticleSystem があります。OrbitControls を使用してズームおよびパンすると、表示可能な領域の中心に最も近いパーティクルを取得したいと考えています。

これには2つの部分があると思います。まず、可視領域の中心頂点を見つける必要があります。次に、中心頂点に最も近い粒子を見つけるために、すべての粒子に対して距離式を実行する必要があります。うまくいけば、これよりも効率的な方法があります。2 番目の部分は、ブルート フォースを使用したかなり単純なものです。最初の部分は、私がよくわからないものです。表示可能領域の中心頂点を見つけるにはどうすればよいですか?

4

3 に答える 3

1

おそらく、10 単位のようにまっすぐ前方にあるポイントを取得し、それに最も近い粒子を取得する必要があります。

この投稿は、これを伝えるのに役立ちます。ところで、私はそれをすべて行ったことがあります。

Three.js プロジェクターと Ray オブジェクト

画面上のポイントをクリックして、そこからベクトルを取得します。

projector = new THREE.Projector();

// This is like clicking on the center of the screen, 0, 0 is center
straight_ahead = new THREE.Vector3(0,0,.5);

// Now we have straight_ahead relative to the camera
projector.unprojectVector(straight_ahead, camera);

// Now straight_ahead is just the direction of the camera, since we're taking away the camera's position from it
straight_ahead.sub(camera.position)

// It's a direction of where the camera is looking, so lets make it 10 units away( pick your own number)
straight_ahead.normalize().multiplyScalar(10)

// Now we we have a length of 10 units, we can get 10 units in front of the camera
straight_ahead.add(camera.position)

// At this point, straight ahead is a point in space 10 units in front of you, so lets find the closest point to that

// here's where you put a simple loop in
min_point = null
min_distance = 999999999
_.each( my_particles, function(particle) {
  distance = particle.position.distanceTo(straight_ahead)
  if (distance < min_distance) {
    min_point = particle
    min_distance = distance
  }
});

// now you have min_point, which should be the closest point to 10 feet in front of your face
于 2013-11-04T18:14:50.307 に答える
0
lookAt = camera.lookAt;
pos = camera.position;

min = MAX_FLOAT, min_index = -1;
foreach(particle in particle_system) {
    d = distance(particle.position, lookAt, pos);
    if( min>d ) { min_index = particle.getIndex; min = d; }
}

関数distanceはネット上で見つけることができます。例: http://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line

これは疑似コードです。それが何をするか、それは視線(lookAtベクトル)を見つけ、そこから最も近い粒子を見つけます。

編集:

var cam_position = camera.position,
    cam_eyeVec = getEyeVec(camera.projectionMatrix);

var min_dist = 10000000,
    min_index = -1;

for(var i=0; i<particle_count; i++) {
    var d = distance(particle[i].position, cam_eyeVec, cam_position);
    if(min_dist > d) {
         min_index = i;
         min_dist = d;
    }
}

function getEyeVec(projMat) {
    return new THREE.Vector3(projMat[8], projMat[9], projMat[10]);
}

function distance(p, n, a) {
    n = n.normalize();
    var diff = new THREE.Vector3(a.x-p.x, a.y-p.y, a.z-p.z);
    var diff_n = diff.multiply(n);
    var d = ((diff.selfSubstract(diff_n)).selfMultiply(n)).length();
    return d;
}

の計算は、viewMatrix からの目とアップのベクトルにgetEyeVec基づいています。の計算は以下に基づいています -ポイントからラインまでの距離distance

于 2013-10-22T18:08:59.410 に答える