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