Domanda

Ho un oggetto proiettile che si muove lungo un vettore di velocità. Devo assicurarmi che l'oggetto sia sempre rivolto nella direzione del vettore di velocità. Inoltre, sto rappresentando la rotazione degli oggetti usando quaternioni, non matrici.

So che il primo passo è trovare una base ortogonale:

forward = direction of velocity vector
up = vector.new(0, 1, 0)
right = cross(up, forward) 
up = cross(forward, right)

Come potrei convertire la base in un quaternione di rotazione?

Soluzione

Nota, vorrei dare credito a Noel Hughes per aver fornito la risposta, ma voglio chiarire con le mie esperienze. Segue lo pseudocodice:

   vec3 vel = direction of velocity vector
   vec3 forward = (1, 0, 0)  // Depends on direction your model faces. See below.
   vec3 axis = cross(forward, vel)
   if (axis == 0) then quit // Already facing the right direction!
   axis = normalize(axis)
   float theta = acos(vel.x/sqrt(vel.x^2, vel.y^2, vel.z^2))
   quat result = (0, axis.y * sin(theta/2), axis.z * sin(theta/2), cos(theta/2)

L'ultimo elemento del quaternione è la parte scalare, i primi tre elementi sono le parti immaginarie. Inoltre, lo pseudocodice sopra presuppone che il tuo oggetto in "spazio modello" punta verso il basso l'asse x positivo. Nel mio caso, l'oggetto in realtà puntava verso il basso l'asse y positivo, nel qual caso ho apportato le seguenti modifiche:

   vec3 vel = direction of velocity vector
   vec3 forward = (0, 1, 0)  // Note that y-component is now 1
   vec3 axis = cross(forward, vel)
   if (axis == 0) then quit 
   axis = normalize(axis)
   float theta = acos(vel.x/sqrt(vel.x^2, vel.y^2, vel.z^2))
   quat result = (axis.x * sin(theta/2), 0, axis.z * sin(theta/2), cos(theta/2)
   // Note that SECOND component above is now 0
È stato utile?

Soluzione

Presumo che non ti interessi dell'orientamento del tuo proiettile, a parte il fatto che l'asse longitudinale è allineato con il vettore di velocità e che l'asse longitudinale è l'asse x di (1, 0, 0).

Sei sulla strada giusta. Normalizza il vettore di velocità, (vx, vy, vz) / sqrt (vx ^ 2 + vy ^ 2 + vz ^ 2) attraversa l'asse x con esso e normalizza il risultato - (0, yn, zn) - questa è la rotazione asse per il quaternione. L'angolo di rotazione è semplicemente theta = coseno inverso di vx / sqrt (vx ^ 2 + vy ^ 2 + vz ^ 2). Il quaternione risultante è quindi

(0, yn, zn) sn (theta / 2) cos (theta / 2)

Fammi sapere se hai domande.

Noel Hughes nhughes1ster@gmail.com

Altri suggerimenti

Darei un'occhiata a libreria vecmath (Java). È passato molto tempo e lo usiamo nella nostra comunità. Si basa su 4 tuple e sarei deluso se non ci fossero metodi semplici per la trasformazione.

Scriverei anche unit test per i risultati attesi. È molto facile confondere i frame positivi e negativi, mancini e destrorsi e movinig / di riferimento. Inizia con quelli semplici (ad esempio xyz) per assicurarti di avere la risposta giusta.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top