2013-03-05 9 views
27

私は、この絵は最高の私の問題を説明すると思う:THREE.jsで地球上のいくつかの衛星をどのように回転させるのですか?

hooray for optical illusions

まず、私は赤い線に沿ってボックスを翻訳します。次に、回転の効果をaの青い線にしたいが、実際に起こっていることは、青い線のほうがbのほうがよく似ています。回転を変更することは常に元のオブジェクト空間を基準にしているように感じられますが、最初に起こったにもかかわらず変換は常に親に対して相対的であり、オブジェクト空間に関連してジオメトリ点に実際には影響しません。私はそれが混乱している場合はお詫び申し上げます。明らかに私はこれで新しいです。

この効果を生むコードの重要な部分は以下のとおりです。画像の向きは、このコードが生成するものとは異なることに注意してください。画像は効果を明確に示すための一例にすぎません。

var objectContainer = new THREE.Object3D(); 

var tubeRadius = 100; 
var tubeGeometry = new THREE.CylinderGeometry(tubeRadius, tubeRadius, tubeRadius * 3, 36, 1, false); 
var tube = new THREE.Mesh(tubeGeomtry, material); 
scene.add(tube); 

var boxes = new THREE.Object3D(); 
var boxEdge = 50; 
var boxGeometry = new THREE.CubeGeometry(boxEdge, boxEdge, boxEdge); 
var box1 = new THREE.Mesh(boxGeometry, material); 
box1.translateX(tubeRadius + boxEdge/2 + 5); 
box1.translateY(boxEdge/2); 
box1.rotation = new THREE.Vector3(0, 2*Math.PI/3*0, 0); 
boxes.add(box1); 
var box2 = box1.clone(); 
box2.rotation = new THREE.Vector3(0, 2*Math.PI/3*1, 0); 
boxes.add(box2); 
var box3 = box1.clone(); 
box3.rotation = new THREE.Vector3(0, 2*Math.PI/3*2, 0); 
boxes.add(box3); 
scene.add(boxes); 

私は考えることができる唯一の解決策は、別のオブジェクト空間内の各ボックスをラップし、その周りを回転するようですが、それは、過剰な仕事のように思えます。私が探している結果を達成するための好ましい方法は何ですか?

+0

私はThree.jsは分かりませんが、Math.cos(rotation)* boxEdge/2、Math.sin(rotation)* boxEdge/2'だけでなくローカルローテーションでそれをどう翻訳すればよいですか? – Ryan

+0

これは、二重の作業のように感じ、各ボックスを回転して翻訳します。本当に私がしたいのは、翻訳前の起点である同じ点について各クローンを回転させることです。 –

答えて

29

あり、あなたが望むものをやってのいくつかの方法がありますが、私は最も簡単でとても似ていると思う:

parent.rotation.z += 0.01; 

EDIT:あなたのレンダリングループ内で次に

// parent 
parent = new THREE.Object3D(); 
scene.add(parent); 

// pivots 
var pivot1 = new THREE.Object3D(); 
var pivot2 = new THREE.Object3D(); 
var pivot3 = new THREE.Object3D(); 

pivot1.rotation.z = 0; 
pivot2.rotation.z = 2 * Math.PI/3; 
pivot3.rotation.z = 4 * Math.PI/3; 

parent.add(pivot1); 
parent.add(pivot2); 
parent.add(pivot3); 

// mesh 
var mesh1 = new THREE.Mesh(geometry, material); 
var mesh2 = new THREE.Mesh(geometry, material); 
var mesh3 = new THREE.Mesh(geometry, material); 

mesh1.position.y = 5; 
mesh2.position.y = 5; 
mesh3.position.y = 5; 

pivot1.add(mesh1); 
pivot2.add(mesh2); 
pivot3.add(mesh3); 

:更新されたフィドル:http://jsfiddle.net/hbt9c/317/

three.js r.70

+0

この例をありがとう。私がこの質問で言及したように、これは私が考えていたものです。これは問題の典型的な解決策ですか?私はこれをしばらく開発しようとしています。私は自分自身を足で撃っていないことを確認したいだけです。 –

+0

はい。典型的です。もう1つの解決策は、各ボックスをシーンの子にし、数式を使用してフレームごとに新しい「位置」と「回転」ベクトルを計算することです。 – WestLangley

5

中心を内側のオブジェクトが回転するポイントとなる複合オブジェクトを作成することは明らかな答えの1つで、非常に素早く作成できます。 Object3Dを作成し、ボックスを追加してください。

同様のアプローチは、this questionでカバーされています。それはオブジェクトの頂点のポイントをシフトするので、効果的に新しい中心を持ちます。

また、行列を手動で混乱させることもできます。これを試してみてください:

var boxGeometry = new THREE.CubeGeometry(boxEdge, boxEdge, boxEdge); 
var mr = new THREE.Matrix4(); 
var mt = new THREE.Matrix4(); 
mt.setPosition(new THREE.Vector3(0,tubeRadius,0)); 
var box1 = new THREE.Mesh(boxGeometry, material); 
box1.applyMatrix(mt); 
var box2 = box1.clone(); 
mr.makeRotationZ(2 * Math.PI /3); 
box2.applyMatrix(mr); 
boxes.add(box2); 
var box3 = box1.clone(); 
mr.makeRotationZ(4 * Math.PI /3); 
box3.applyMatrix(mr); 
boxes.add(box3); 
boxes.add(box1); 
scene.add(boxes); 
関連する問題