0
$\begingroup$

I need to generate a random rotation matrix for a given angle $a$. In other words, a random $n\times n$ matrix $A$ such that for any unit-length vector $v$ the following is true.

$$v'Av\le\cos a$$

The recipe below visualizes 10000 random rotations with "small" angles, can anyone see how to make it work with specific angle $a$? For $a=\pi/2$ and $n=3$, these rotations correspond to points along the equator in the visualization below

(* generate random rotation matrix corresponding to a "small" rotation *)

randomRotation2[n_] := 
  Module[{}, 
   z = IdentityMatrix[n] + 
     0.1 RandomVariate[NormalDistribution[0, 1], {n, n}];
   {q, r} = QRDecomposition[z];
   d = Diagonal[r];
   ph = d/Abs[d];
   q*ph];

n = 3;
points = Table[randomRotation2[n].{0, 0, 1}, {10^4}];
Graphics3D[{{Gray, PointSize[Small], Point[points]}, {Red, Thick, 
   Arrow[{{0, 0, 0}, {0, 0, 1}}]}}, Axes -> True]

enter image description here

$\endgroup$
3
  • $\begingroup$ Can't you use RotationMatrix[a,{u,v}] with random vectors u,v? From the documentation of RotationMatrix: gives the matrix that rotates by $a$ radians in the plane spanned by $u$ and $v$. $\endgroup$
    – anderstood
    Oct 30 '20 at 10:28
  • $\begingroup$ "a random n×n matrix A such that for any unit-length vector v the following is true: ..." That is only true in 2D. $v^\top A v = 1$ if $v$ is a unit vector along the rotation axis (try {1, 0, 0}.RotationMatrix[alpha, {1, 0, 0}].{1, 0, 0} for instance). $\endgroup$
    – anderstood
    Oct 30 '20 at 11:01
  • $\begingroup$ you are right, it needed to be <= insteda of ==, fixed $\endgroup$ Oct 30 '20 at 18:21
2
$\begingroup$

Edit

For the band region.

bandReg = 
  RegionIntersection[HalfSpace[{0, 0, -1}, {0, 0, 0.8}], 
   HalfSpace[{0, 0, 1}, {0, 0, 0.9}], Sphere[]];
RotationMatrix[{RandomPoint[bandReg], {0, 0, 1}}]
Graphics3D[{Point[RandomPoint[bandReg, 2000]], Opacity[0.1], Ball[]}]

enter image description here

Update

n = 8;
normal = SparseArray[i_ /; i == n -> -1, {n}] // Normal
pt = SparseArray[i_ /; i == n -> 0.8, {n}] // Normal
center = center = ConstantArray[0, n];
a = HalfSpace[normal, pt] // Region;
b = Sphere[center, 1] // Region;
reg = RegionIntersection[a, b]
RotationMatrix[{RandomPoint[reg], normal}]

Original

Maybe this?

Or do you want to get angle instead of vector or point?

The answer need to be updated later.

a = HalfSpace[{0, 0, -1}, {0, 0, 0.8}] // Region;
b = Sphere[] // Region;
reg = RegionIntersection[a, b]
RotationMatrix[{RandomPoint[reg], {0, 0, 1}}]
Graphics3D[{Point[RandomPoint[reg, 2000]], Opacity[0.1], Ball[]}]

enter image description here

$\endgroup$
2
  • $\begingroup$ thanks, that's a useful trick....any idea how to exclude rotations close to origin? I tried RegionIntersection[a, b, RegionDifference[FullRegion[3], HalfSpace[{0, 0, -1}, {0, 0, 0.9}]]] but RandomPoint fails to evaluate for that region $\endgroup$ Oct 30 '20 at 18:31
  • $\begingroup$ @YaroslavBulatov I have edited the answer. $\endgroup$
    – cvgmt
    Oct 31 '20 at 0:06
2
$\begingroup$

Assuming OP requires rotation matrices for $n\ge 3$ and adapting the algorithm given in https://stackoverflow.com/a/50342248/6644522 for Mathematica the following function genM generates a $n\times n$ rotation matrix given an axis of rotation v in form of an $(n-1)$-subspace (a $n\times(n-1)$ matrix) and an angle theta.

ArcTan2[y_,x_]/;x\[Element]Reals&&y\[Element]Reals:=Which[x>0||y!=0,2ArcTan[y/(Sqrt[x^2+y^2]+x)],x<0&&y==0,\[Pi],x==0&&y==0,Indeterminate]

genM[v_List,theta_]:=Module[{n,u,M,c,r,t,R},
   n=Length[v[[All,1]]];
   u=v;
   M=IdentityMatrix[n];
   For[c=1,c<=n-2,c++,
      For[r=n,r>=c+1,r--,
         t=ArcTan2[u[[r,c]],u[[r-1,c]]]//N;
         R=IdentityMatrix[n];
         R[[r-1;;r,r-1;;r]]={{Cos[t],-Sin[t]},{Sin[t],Cos[t]}}\[Transpose];
         u=R.u;
         M=R.M;
      ];
   ];
   R=IdentityMatrix[n];
   R[[n-1;;n,n-1;;n]]={{Cos[theta],-Sin[theta]},{Sin[theta],Cos[theta]}};
   LeastSquares[M,R.M]
]

where I implemented ÀrcTan2 based on https://en.wikipedia.org/wiki/Atan2. Running

genM[{{1}, {2}, {3}}, \[Pi]/4] // N // MatrixForm
genM[{{1, 0}, {0, 1}, {1, 0}, {0, 1}}, \[Pi]/4] // N // MatrixForm

gives results consistent with https://stackoverflow.com/a/50342248/6644522:

Matrices

and the three dimensional rotation matrix is equivalent to RotationMatrix[\[Pi]/4, {1, 2, 3}] within floating point precision. The math behind this (I have not looked into it) can supposedly be found in http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.4.8662.

I am not 100% sure that this implementation in Mathematica is correct: I had to add a Transpose, adapt some spans and I do not know if the implementation of ArcTan2 I have chosen is consistent with atan2 in MATLAB. I ran some test on against RotationMatrix with random angles and axes and in $n=3$ the code seems to work but for $n>3$ I only checked against the on example given for the MATLAB code.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.