2014-08-08 7 views
6

Poszukuję sposobu znalezienia macierzy rotacji między dwoma zdefiniowanymi wektorami w THREE.js.Jak znaleźć macierz obrotu między dwoma wektorami w THREE.js

Na przykład

v1 = new THREE.Vector3(1, 1, 1) v2 = new THREE.Vector3(1, 1, -1)

trzeba tej macierzy rotacji do obracania całego obiektu w następnym etapie.

+1

Jest to non SO pytanie, przy okazji zajrzeć tutaj http://gamedev.stackexchange.com/questions/20097/how- obliczyć-od-3x3-macierz-od-2-kierunku-wektorów –

+0

i to jest dokumentacja vector3 http://threejs.org/docs/#Reference/Math/Vector3 –

+0

To pytanie wydaje się być wyłączone temat, ponieważ chodzi o http://math.stackexchange.com/ –

Odpowiedz

14

Można zdefiniować obrót z dwoma wektorami jednostka długości v1 i v2 tak:

var quaternion = new THREE.Quaternion(); // create one and reuse it 

quaternion.setFromUnitVectors(v1, v2); 

w Twoim przypadku, trzeba znormalizować swoje wektory pierwszy.

Można wtedy zastosować ten obrót do obiektu za pomocą następującego wzoru:

var matrix = new THREE.Matrix4(); // create one and reuse it 

matrix.makeRotationFromQuaternion(quaternion); 

object.applyMatrix(matrix); 

Ewentualnie, jeśli nie wymaga matrycy, można po prostu zastosować kwaternion bezpośrednio:

object.applyQuaternion(quaternion); 

three.js r.86

+0

Witam. Dzięki, wydaje się, że działa. Byłoby wspaniale mieć to rozwiązanie bez zależności quaternion. – kriskodzi

+3

three.js jest oparty na kwaternionach. Ale jeśli nalegasz, najpierw normalizuj swoje wektory i ustaw "axis.cross (v1, v2); angle = v1.angleTo (v2); matrix.makeRotationAxis (oś, kąt); object.applyMatrix (matrix); ' – WestLangley

+0

Tak, właśnie tego szukam. Myślę, że możesz dodać to do swojej odpowiedzi, a następnie zaznaczę to jako zaakceptowane. – kriskodzi

1

Używam quaternions zamiast tego zrobiłbym tak (nie używaj THREE.js):

konstrukt przekształcania 4x4 matrycę pierwszy wektor V1 (V1, V2 kładzie na jego płaszczyźnie XY i V1 jest oś X)

double V1[3],V2[3]; // input 
double X[3],Y[3],Z[3],P[3]; // output 
double m[16]; // OpenGL like transform matrix 
X = V1; 
Z = V1 x V2; 
Y = X x Z; 
X/=|X|; 
Y/=|Y|; 
Z/=|Z|; 
P = (0,0,0); 
m[ 0]=X[0]; 
m[ 1]=X[1]; 
m[ 2]=X[2]; 
m[ 3]=0; 
m[ 4]=Y[0]; 
m[ 5]=Y[1]; 
m[ 6]=Y[2]; 
m[ 7]=0; 
m[ 8]=Z[0]; 
m[ 9]=Z[1]; 
m[10]=Z[2]; 
m[11]=0; 
m[12]=P[0]; 
m[13]=P[1]; 
m[14]=P[2]; 
m[15]=1; 

teraz zastosować obrót macierzą transformacji wokół osi Z na nim

double angle = acos((V1.v2)/(|V1|.|V2|)) 
  • obracać wokół osi z o +/- kąta
  • kąt znak zależy od osi Y przejechać argumenty zamówienia
  • nie
  • pewien teraz od Głowica ale widać
  • jeśli ustawisz go źle V2 będzie po przeciwnej stronie
+0

Cześć, dzięki za wskazówkę, I właśnie to testuję. Co właściwie masz na myśli, mówiąc o matrycy transformacji rotacji _apply na osi Z.Chcesz, żebym zastosował matrycę do obiektu, a następnie obróciłem ją wokół Z, więc będziemy musieli zastosować 2 obroty? – kriskodzi

+1

@RecRoot m [] zawiera macierz transformacji reprezentującą układ współrzędnych V1. musisz mnożyć macierz m przez macierz rotacji (wokół Z kątem), która obraca układ współrzędnych od V1 do V2. Nie ma znaczenia, czy zastosujesz obiekt * m * rotz lub M = m * rotz, a następnie obj * M jedyną różnicą jest to, że kiedy tworzysz M, wtedy masz mniej operacji (tylko raz pomnóż macierz przez macierz nie dla każdego wierzchołka obiektu. ..) możesz google jak wygląda macierzy transformacji dla obrotu wokół Z (jest to podstawowe i myślę, że twoja struktura ma natywnie w niektórych funkcji) – Spektre

+0

@RecRoot btw patrz tutaj: http://stackoverflow.com/a/25216549/ 2521214, aby uzyskać więcej informacji o składzie macierzy transformacji. – Spektre

Powiązane problemy