Re: Re: Solve & RotationMatrix

*To*: mathgroup at smc.vnet.net*Subject*: [mg76070] Re: [mg76002] Re: Solve & RotationMatrix*From*: DrMajorBob <drmajorbob at bigfoot.com>*Date*: Wed, 16 May 2007 05:16:05 -0400 (EDT)*References*: <f21g0q$7d6$1@smc.vnet.net> <f23qq6$oa3$1@smc.vnet.net> <31173113.1179139106764.JavaMail.root@m35>*Reply-to*: drmajorbob at bigfoot.com

There MUST be a built-in solver I'm missing, but here's a version 6.0 solver, anyway. For version 5, you'd have to replace RandomReal with RandomArray or a Table of Random[] entries. I'm not sure if there are other issues or not; I've moved on! randomRotationMatrix creates problems, and angleVector solves them. angleVector uses Eigenvectors to find the axis of rotation, NullSpace to find two perpendiculars to it, uses FindRoot to find the angle that allows m[t].perp == target.m for both perpendiculars, and uses Mod to scale the answer to the range -Pi to Pi. The code assumes the matrix is real, has a real eigenvector, and IS a rotation matrix. If not, FindRoot will fail messily. I haven't allowed for difficulties due to imprecision in the input, which could also cause FindRoot to fail. To take care of that, you could replace FindRoot with FindMinimum applied to a sum of squared errors. Of course, the axis is unique only up to a sign change. (* code *) Clear[realQ, realSelect, error, randomRotationMatrix, angleVector] Off[Solve::"ifun"] realQ[z_?NumericQ] := Re[z] == z realQ[v_?VectorQ] := VectorQ[v, realQ] realQ[v_?MatrixQ] := MatrixQ[v, realQ] realSelect[m_?MatrixQ] := First@Select[m, realQ] error[target_?MatrixQ, perp_?VectorQ, m_?MatrixQ] := #.# &[ target.perp - m.perp] error[target_?MatrixQ, perps_?MatrixQ, m_?MatrixQ] := Chop@Total[error[target, #, m] & /@ perps] randomRotationMatrix[] := Module[{t, v}, t = RandomReal[{-Pi, Pi}]; v = Normalize@Table[RandomReal[], {i, 3}]; {"angle" -> t, "axis" -> v, "rotation matrix" -> RotationMatrix[t, v]}] angleVector[target_?MatrixQ] /; realQ[target] := Module[{v, t, m, perps, root}, v = realSelect@Eigenvectors[target]; m = RotationMatrix[t, v]; perps = Normalize /@ NullSpace[{v}]; root = FindRoot[error[target, perps, m] == 0, {t, 0}]; {"angle" -> Mod[t /. root, 2 \[Pi], -\[Pi]], "axis" -> v} ] (* create a test problem *) randomRotationMatrix[] // TableForm target = "rotation matrix" /. %; angle->2.21203 axis->{0.768799,0.272468,0.578541} rotation = matrix->{{0.346426,-0.128843,0.929187},{0.798396,-0.479535,-0.364156},{0.492497,0.868012,-0.0632556}} (* solve for the angle and vector *) angleVector[target] {angle->2.21203,axis->{0.768799,0.272468,0.578541}} Bobby On Mon, 14 May 2007 04:49:33 -0500, Mathieu G <ellocomateo at free.fr> wrote: > CKWong.P at gmail.com a =E9crit : >> Obviously, you need to provide the function RotationMatrix[ angle, >> axisVector ] for the algorithm to work. >> >> On the other hand, matrices for rotations about the Cartesian axes, >> i.e., RotX,RotY, & RotZ, can be written done directly. Why not do so? >> >> > Hi, > Thank you for your reply. > I am not interested in a simple rotation matrix around an axis, but in > finding the angles corresponding to a 3D rotation matrix. > I compute VectN which is the vector normal to my surface, and I am > interested in getting the rotation parameters that bring VectY to VectN. > Regards, > Mathieu > > -- DrMajorBob at bigfoot.com