2009-10-25 3 views
4

Disons que j'ai deux points dans l'espace 3D (a et b) et un vecteur axe/unité fixe appelé n. Je veux créer une matrice de rotation qui minimise la distance euclidan entre le point a (non tourné) et le point tourné b.Matrice de rotation qui minimise la distance

par exemple:

Q := matrix_from_axis_and_angle (n, alpha); 

find the unknown alpha that minimizes sqrt(|a - b*Q|) 

BTW - Si est plus facile exprimé une solution/algorithme avec l'unité-escouades aller de l'avant et de les utiliser. Je viens d'utiliser des matrices pour formuler ma question parce qu'elles sont plus largement utilisées.


Oh - Je sais qu'il ya certains cas dégénérés (a ou b couché exactement en ligne avec n ect.) Ceux-ci peuvent être ignorés. Je cherche juste le cas où une seule solution peut être calculée.

+0

En supposant que toutes les rotations tournent autour de l'origine si vous faites une rotation b de sorte qu'elle tombe sur le vecteur, cela n'assure-t-il pas la distance minimale (ou maximale)? –

+0

Ou supposons-nous n fixé? –

+1

n est fixé ... malheureusement, je ne peux pas le changer. Sinon, ce serait très simple. –

Répondre

5

semble assez facile. Supposons que le vecteur d'unité n implique une rotation autour d'une ligne parallèle à n au point x0. Si x0! = L'origine, traduisez le système de coordonnées par -x0 pour obtenir les points a' et b' par rapport à l'origine 0 du nouveau système de coordonnées, et utilisez ces 2 points au lieu de a et b.

1) calculer vecteur ry = nxa

2) calculer vecteur unitaire uy = vecteur unitaire dans la direction ry

3) calculer vecteur unitaire ux = uy xn

Vous avez maintenant un triplet de vecteurs unitaires mutuellement perpendiculaires ux, uy et n, qui forment un système de coordonnées droitier. On peut montrer que:

a = dot(a,n) * n + dot(a,ux) * ux 

En effet vecteur unitaire uy parallèle à ry qui est perpendiculaire à la fois a et n.(de l'étape 1)

4) Calculer les composantes de b le long des vecteurs unitaires ux, uy. Les composantes de a sont (ax, 0) où ax = dot (a, ux). Les composantes de b sont (bx, by) où bx = point (b, ux), par = point (b, uy). En raison du système de coordonnées droit, ax est toujours positif, donc vous n'avez pas besoin de le calculer.

5) Calculer thêta = atan2 (par, bx).

Votre matrice de rotation est celle qui tourne d'un angle thêta par rapport au système de coordonnées (ux, uy, n) autour de l'axe n.

Ceci donne des réponses dégénérées si a est parallèle à n (étapes 1 et 2) ou si b est parallèle à n (étapes 4, 5).

+0

+1 pour identifier les cas dégénérés! – unutbu

2

Je pense que vous pouvez reformuler la question:

quelle est la distance d'un point à un cercle 2d dans l'espace 3D.

la réponse se trouve here

de sorte que les étapes nécessaires sont les suivantes:

  • tournant le point b autour d'un vecteur n vous donne un cercle 2d dans l'espace 3D
  • en utilisant ce qui précède , trouvez la distance à ce cercle (et le point sur le cercle)
  • le point sur le cercle est le point b que vous recherchez.
  • déduire l'angle de rotation

... ou quelque chose; ^)

2

la distance est réduite au minimum lorsque le vecteur à partir d'une ligne le long de la n lignes vers le haut avec le vecteur de b à la ligne le long de n.

Projetez a et b dans le plan perpendiculaire à n et résolvez le problème en 2 dimensions. La rotation que vous obtenez est la rotation dont vous avez besoin pour minimiser la distance.

2

Soit P le plan perpendiculaire à n. Nous pouvons trouver la projection d'un dans le plan P, (et de même pour b):

a' = a - (dot(a,n)) n 
b' = b - (dot(b,n)) n 

où le point (a, n) est le produit scalaire de a et n

a » et b 'se trouvent dans le plan P.

Nous avons maintenant réduit le problème à 2 dimensions. Yay! L'angle (de rotation) entre a 'et b' est égal à l'angle (de rotation) nécessaire pour balancer b autour de l'axe n de manière à être le plus proche de a. (Pensez aux ombres projetées sur l'avion P).

L'angle entre 'et b' est facile à trouver:

dot(a',b') = |a'| * |b'| * cos(theta) 

pour Solve thêta.

Vous pouvez maintenant trouver la matrice de rotation donnée thêta et n ici: http://en.wikipedia.org/wiki/Rotation_matrix

Jason S souligne à juste titre que, une fois que vous savez thêta, vous devez quand même décider de tourner b dans le sens horaire ou antihoraire sur le n-axe. La quantité, point ((a x b), n), sera une quantité positive si (a x b) est dans la même direction que n, et négative si (a x b) est dans la direction opposée. (Elle n'est jamais nulle tant que ni ni b n'est colinéaire avec n.)

Si (axb) est dans la même direction que n, alors b doit être tourné dans le sens des aiguilles d'une montre de l'angle thêta autour de l'axe n .

Si (a x b) est dans la direction opposée, alors b doit être tourné dans le sens des aiguilles d'une montre de l'angle -theta autour de l'axe n.

+0

votre valeur de thêta est unique à moins de 180 degrés; vous avez besoin d'un moyen de choisir thêta ou thêta + 180degrees. –

+0

Lors de la résolution de l'angle entre a 'et b' en utilisant l'équation du produit scalaire, il est habituel de prendre thêta entre 0 et pi radians. Tant que a et b ne sont pas colinéaires avec n, l'angle thêta est unique. – unutbu

+0

Je comprends cela. L'angle thêta = inv_cos (...) est unique, par convention, généralement mappé sur la plage positive [0, pi] comme vous le dites.Mais l'angle de rotation nécessaire pour résoudre ce problème est un angle unique dans la plage [0,2 * pi). Mon commentaire précédent était légèrement faux, vous devez choisir soit + thêta ou -theta. Un de ces angles va osciller b donc il est coplanaire avec les vecteurs a et n. L'autre angle ne sera pas. –

Questions connexes