2017-07-17 2 views
1

J'ai deux vecteurs distincts de points de données 3D qui représentent des courbes et je suis en train de les tracer comme des données de dispersion dans un tracé 3D avec matplotlib.Calculer la matrice de rotation pour aligner deux vecteurs dans l'espace 3D?

Les deux vecteurs commencent à l'origine, et les deux ont une longueur unitaire. Les courbes sont similaires les unes aux autres, cependant, il y a généralement une rotation entre les deux courbes (à des fins de test, j'utilise en fait une courbe et j'applique une matrice de rotation pour créer la deuxième courbe).

Je souhaite aligner les deux courbes de sorte qu'elles s'alignent en 3D, par ex. tourner la courbe b, de sorte que ses points de départ et d'arrivée s'alignent avec la courbe a. J'ai essayé de faire ceci en soustrayant le dernier point du premier, pour obtenir un vecteur de direction représentant la ligne droite du début à la fin de chaque courbe, en les convertissant en vecteurs unitaires et en calculant ensuite les produits croisés et les points. en utilisant la méthodologie décrite dans cette réponse (https://math.stackexchange.com/a/476311/357495) pour calculer une matrice de rotation.

Cependant, quand je fais cela, la matrice de rotation calculée est fausse et je ne sais pas pourquoi?

Mon code est ci-dessous (j'utilise Python 2.7):

# curve_1, curve_2 are arrays of 3D points, of the same length (both start at the origin) 

curve_vec_1 = (curve_1[0] - curve_1[-1]).reshape(3,1) 
curve_vec_2 = (curve_2[index][0] - curve_2[index][-1]).reshape(3,1) 
a,b = (curve_vec_1/ np.linalg.norm(curve_vec_1)).reshape(3), (curve_vec_2/ np.linalg.norm(curve_vec_2)).reshape(3) 
v = np.cross(a,b) 
c = np.dot(a,b) 
s = np.linalg.norm(v) 
I = np.identity(3) 
vXStr = '{} {} {}; {} {} {}; {} {} {}'.format(0, -v[2], v[1], v[2], 0, -v[0], -v[1], v[0], 0) 
k = np.matrix(vXStr) 
r = I + k + np.square(k) * ((1 -c)/(s**2)) 

for i in xrange(item.shape[0]): 
    item[i] = (np.dot(r, item[i]).reshape(3,1)).reshape(3) 

Dans mon cas de test, la courbe 2 est simplement la courbe 1 avec la matrice de rotation suivante appliquée:

[[1 0  0 ] 
[ 0 0.5  0.866] 
[ 0 -0.866 0.5 ]] 

(juste une rotation de 60 degrés autour de l'axe x).

La matrice de rotation calculée par mon code pour aligner les deux vecteurs de nouveau est la suivante:

[[ 1.   -0.32264329 0.27572962] 
[ 0.53984249 1.   -0.35320293] 
[-0.20753816 0.64292975 1.  ]] 

Le graphique des vecteurs de direction pour les deux courbes originales (a et b respectivement dans le bleu et le vert) et le résultat de b transformé avec la matrice de rotation calculée (rouge) est ci-dessous. J'essaie de calculer la matrice de rotation pour aligner le vecteur vert sur le bleu. Curve plot

Répondre

2

Le problème est ici:

r = I + k + np.square(k) * ((1 -c)/(s**2)) 

np.square(k) carrés chaque élément de la matrice. Vous voulez np.matmul(k,k) ou k @ k qui est la matrice multiplié par lui-même.

Je mettrais également en œuvre les valises latérales (en particulier s=0) mentionnées dans les commentaires de cette réponse ou vous vous retrouverez avec des erreurs dans un certain nombre de cas.

+0

Merci - cela le répare! Comme j'utilise numpy <1.10, j'ai utilisé np.dot (k, k) au lieu de matmul. Je vais mettre en œuvre les cas limites, juste nécessaire pour que le scénario de base fonctionne en premier. :) – Mark