2013-05-01 12 views
11

Ho un problema. In Three.js, voglio ruotare una sfera (Terra) attorno all'asse inclinato di 23,5 gradi. Ho trovato sphere.rotation.x, sphere.rotation.y e sphere.rotation.z, ma quando li combino nel rapporto corretto, la rotazione della sfera è piuttosto strana - non ha un asse di rotazione permanente. Penso di aver bisogno di una funzione come sphere.rotation.vector (1,0, -1). Qualcuno sa come viene chiamata questa funzione e qual è la sintassi corretta?Three.js - Rotazione di una sfera attorno a un determinato asse

Mille grazie per le risposte!

risposta

17

Per questo è necessario utilizzare quaternions. This video spiega quali sono i quaternari e come vengono utilizzati nella grafica 3D.

è possibile costruire un quaternione come questo:

quaternion = new THREE.Quaternion().setFromAxisAngle(axisOfRotation, angleOfRotation); 

quindi si applica al vostro oggetto:

object.rotation.setEulerFromQuaternion(quaternion); 

È possibile anche ottenere questo utilizzando gerarchie di oggetti. Ad esempio, è possibile creare un'istanza Object3D() e inclinarla di 23,5 gradi, quindi creare una sfera (Terra) e aggiungerla all'oggetto inclinato. La sfera ruoterà quindi attorno all'asse Y inclinato. Tuttavia, i quaternioni sono lo strumento migliore per risolvere questo problema.

+0

grazie mille! funziona bene :) – karlosss

+5

Poiché threejs r59 'setEulerFromQuaternion()' è stato rimosso (consultare: https://github.com/mrdoob/three.js/wiki/Migration#r58--r59). La seconda riga ora dovrebbe essere: 'object.rotation = new THREE.Euler(). SetFromQuaternion (quaternion);' – kontur

19

Non devi capire come gli angoli di Eulero oi quaternioni lavorano per fare ciò che vuoi. È possibile utilizzare

Object3D.rotateOnAxis(axis, angle); 

Assicurarsi axis è un vettore unitario (ha lunghezza 1), e angle è in radianti.

Object3D.rotateOnAxis(axis, angle) ruota su un asse nello spazio oggetti.

Three.js r.67

+0

Grazie per il tuo aiuto, ma sono un principiante in three.js e non sono ancora in grado di utilizzare Object3D ... ti credo che funzioni bene, ma ho usato i quaternioni. – karlosss

+0

@karlosss Object3D è una classe base da cui discendono molti oggetti in Three.js. Se il tuo oggetto ha un attributo di rotazione, allora è probabilmente una sottoclasse di Object3D. L'asse – Joel

+0

ha lunghezza 3. –

0
var quaternion = new THREE.Quaternion(); 
var object = scene.getObjectByName('xxx'); 
function render(){ 
    quaternion.setFromAxisAngle(new THREE.Vector3(0, 1, 0).normalize(), 0.005); 
    object.position.applyQuaternion(quaternion); 
} 

Three.js versioni 86, vedi full example on codepen.

+1

Quante volte al secondo istanziate un 'Quaternion',' Vector3' e 'Euler'? Crea invece un'istanza del quaterio al di fuori del ciclo di rendering. Nel ciclo di rendering, fai questo: 'planet.position.applyQuaternion (quaternion);' Inoltre, chiama scene.getObjectByName() una volta fuori dal ciclo. – WestLangley

+0

Bel suggerimento. È semplice esprimere come ruotare attorno a qualsiasi asse usando il codice sopra. Lo ottimizzo nel [esempio completo] (https://codepen.io/luics/pen/GEbOYO) ora. – luics

+0

Vieni. Non hai seguito il mio suggerimento. Imposta 'quaternion' una volta all'esterno del ciclo di rendering. Rimuovi 'euler'. Chiama invece 'applyQuaternion()'. – WestLangley