2017-07-12 2 views
0

同じVector3の点を中心にして、異なる方向に複数のオブジェクトを回転しようとしています。THREE.js trigを使用した点の周りのランダムな多方向の軌道

私は、キャンバスの上にラベルDIVを貼り付けるために3Dベクトルを2D位置に投影しているので、コンテナ内の各オブジェクトを単にラップし、ランダムな回転を適用するだけではなく、プロジェクトクラス。

は、ここですべてのオブジェクトが同じ軌道路に沿ってポイントを中心に回転可能私の現在のコードです:

for(var i = 0; i<objectsArr.length; i++){ 
    var obj = objectsArr[i]; 
    var radius = obj.angle * (Math.PI/180); 
    obj.position.x = obj.radius * Math.cos(radius); 
    obj.position.y = obj.radius * Math.sin(radius); 
    obj.angle += obj.orbitSpeed; 
} 

誰もが、私は彼らがX、Y、Z軸に沿ってランダムな方向に周回させることができる方法を知っていますか?

答えて

0

まず、点について回転するオブジェクトについてはthis answerを参照してください。

コードから、各オブジェクトの軌道速度と現在の回転角(位置に対するベクトルを表す)が格納されているように見えます。 2D角を保存するのではなく、オブジェクトの軌道面の法線を表す(垂直に)Vector3として格納します。 (軌道面を別々に定義することができれば、後で「群れ」を得ることができます。)軌道の速度を1ラジアンで記憶することをお勧めします。したがって、毎回の変換を行う必要はありません。

残りの問題は実際にはVector3.applyAxisAngleメソッドで非常に簡単になります。

いくつかの擬似コード:

  1. は、オブジェクトの位置からの回転点位置を引きます。
  2. オブジェクトの軌道速度と角度を使用して、一時的な位置を更新します。
  3. 回転ポイントの位置をオブジェクトの位置に戻します。

あなたのコードでそれを表示するには:

var obj; 
for(var i = 0; i< objectsArr.length; i++){ 
    obj = objectsArr[i]; 
    obj.position.sub(rotationPoint); // rotationPoint is a Vector3 
    obj.position.applyAxisAngle(obj.angle, obj.orbitSpeed); 
    obj.add(rotationPoint); 
} 

そして、ここでは(10, 10, 10)で「核」について、ランダムに周回するいくつかのオブジェクトのライブデモです。

var renderer, scene, camera, controls, stats, nucleus; 
 

 
var WIDTH = window.innerWidth, 
 
    HEIGHT = window.innerHeight, 
 
    FOV = 60, 
 
    NEAR = 1, 
 
    FAR = 1000; 
 

 
var electrons = [], 
 
    numElectrons = 100; // more electrons = slower updating 
 
function populateScene() { 
 
    var geo = new THREE.SphereBufferGeometry(10, 16, 16); 
 
    var mat = new THREE.MeshPhongMaterial({color:"blue"}); 
 
    nucleus = new THREE.Mesh(geo, mat); 
 
    nucleus.position.set(10, 10, 10); // you can change these values 
 
    scene.add(nucleus); 
 
    
 
    var electron = null, 
 
    plane = new THREE.Plane(), 
 
    point = new THREE.Vector3(); 
 
    geo = new THREE.SphereBufferGeometry(1, 16, 16); 
 
    mat = new THREE.MeshPhongMaterial({color:"red"}); 
 
    for(var i = 0; i < numElectrons; ++i){ 
 
    electron = new THREE.Mesh(geo, mat); 
 
    electrons.push(electron); 
 
    electron.angle = new THREE.Vector3(
 
     Math.random(), 
 
     Math.random(), 
 
     Math.random() 
 
    ).normalize(); 
 
    electron.orbitSpeed = (Math.random() * 0.05) + 0.05; 
 
    if(Math.random() > 0.5) electron.orbitSpeed *= -1; 
 
    plane.normal.copy(electron.angle); 
 
    point.set(Math.random(), Math.random(), Math.random()); 
 
    plane.projectPoint(point, electron.position); 
 
    electron.position.setLength(Math.floor(Math.random() * 20) + 15); 
 
    electron.position.applyAxisAngle(electron.angle, Math.random()/10); 
 
    electron.position.add(nucleus.position); 
 
    scene.add(electron); 
 
    } 
 
} 
 

 
function updateElectrons(){ 
 
    var obj = null; 
 
    for(var i = 0; i < numElectrons; ++i){ 
 
     obj = electrons[i] 
 
     obj.position.sub(nucleus.position); 
 
     obj.position.applyAxisAngle(obj.angle, obj.orbitSpeed); 
 
     obj.position.add(nucleus.position); 
 
    } 
 
} 
 

 
function init() { 
 
    document.body.style.backgroundColor = "slateGray"; 
 

 
    renderer = new THREE.WebGLRenderer({ 
 
    antialias: true, 
 
    alpha: true 
 
    }); 
 
    renderer.shadowMap.enabled = true; 
 
    renderer.shadowMap.type = THREE.PCFSoftShadowMap; 
 

 
    document.body.appendChild(renderer.domElement); 
 
    document.body.style.overflow = "hidden"; 
 
    document.body.style.margin = "0"; 
 
    document.body.style.padding = "0"; 
 

 
    scene = new THREE.Scene(); 
 

 
    camera = new THREE.PerspectiveCamera(FOV, WIDTH/HEIGHT, NEAR, FAR); 
 
    camera.position.z = 100; 
 
    scene.add(camera); 
 

 
    controls = new THREE.TrackballControls(camera, renderer.domElement); 
 
    controls.dynamicDampingFactor = 0.5; 
 
    controls.rotateSpeed = 3; 
 

 
    var light = new THREE.PointLight(0xffffff, 1, Infinity); 
 
    camera.add(light); 
 

 
    stats = new Stats(); 
 
    stats.domElement.style.position = 'absolute'; 
 
    stats.domElement.style.top = '0'; 
 
    document.body.appendChild(stats.domElement); 
 

 
    resize(); 
 
    window.onresize = resize; 
 

 
    populateScene(); 
 

 
    animate(); 
 
} 
 

 
function resize() { 
 
    WIDTH = window.innerWidth; 
 
    HEIGHT = window.innerHeight; 
 
    if (renderer && camera && controls) { 
 
    renderer.setSize(WIDTH, HEIGHT); 
 
    camera.aspect = WIDTH/HEIGHT; 
 
    camera.updateProjectionMatrix(); 
 
    controls.handleResize(); 
 
    } 
 
} 
 

 
function render() { 
 
    renderer.render(scene, camera); 
 
} 
 

 
function animate() { 
 
    requestAnimationFrame(animate); 
 
    updateElectrons(); 
 
    render(); 
 
    controls.update(); 
 
    stats.update(); 
 
} 
 

 
function threeReady() { 
 
    init(); 
 
} 
 

 
(function() { 
 
    function addScript(url, callback) { 
 
    callback = callback || function() {}; 
 
    var script = document.createElement("script"); 
 
    script.addEventListener("load", callback); 
 
    script.setAttribute("src", url); 
 
    document.head.appendChild(script); 
 
    } 
 

 
    addScript("https://threejs.org/build/three.js", function() { 
 
    addScript("https://threejs.org/examples/js/controls/TrackballControls.js", function() { 
 
     addScript("https://threejs.org/examples/js/libs/stats.min.js", function() { 
 
     threeReady(); 
 
     }) 
 
    }) 
 
    }) 
 
})();

three.js R86

関連する問題