2013-03-05 32 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 2013-03-05 02:13:18

+0

这感觉就像双重工作,旋转和翻译每个盒子。真的,我想要做的是旋转每个克隆相同的点,这是翻译之前的原点。 – 2013-03-05 02:16:41

回答

29

有这样做你想要什么的几种方法,但我认为最简单的就是像这样:

// 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); 

然后在您的渲染循环:

parent.rotation.z += 0.01; 

编辑:更新小提琴:http://jsfiddle.net/hbt9c/317/

three.js r.70

+0

谢谢你的例子。正如我在问题中提到的,这就是我的想法。这是这个问题的典型解决方案吗?我打算发展这一段时间,我只是想确保我不会在自己的脚下射击。 – 2013-03-05 10:26:48

+0

是的。这是典型的。另一种解决方案是让每个盒子成为场景的子节点,并使用数学计算每帧的新“位置”和“旋转”矢量。 – WestLangley 2013-03-05 14:39:25

5

创建一个复合对象,其中心将成为内部对象旋转的点,这是一个明显的答案,并且写起来非常快。只需创建一个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);