I don't know what I was thinking when I posted yesterday
about quaternion based rotations, but that was an old routine
that I've replaced by this one, which is simpler. Sorry to
continue a somewhat off-topic post.
------------------------------------------------------------------
NB. Rotate n vectors v about axes u by angles w.
NB. (Makes use of a quaternion-based formula.)
NB. Dimensions of arrays v,u and w are $v --> (n 3).
NB. The axes u must be normalized to unit length.
NB. Usage: v qRot (u;w) --> v' (v' the rotated v)
qRot=: dyad define
'u w'=. y
NB. Add this line if the u's are not normalized.
NB. u=. norm u
u=. u*sin-:w
t=. +: u cross x
x+ (t*cos-:w)+ u cross t
)
L=: +/"1 &. (*:"_) NB. Lengths of vectors
norm=: ] % L NB. normalize to unit length
NB. cross products of vectors: v1 cross v2 --> v1 X v2
cross=: (([: 1&|."1 [)* [: 2&|."1 ])- (([: 1&|."1 [)* [: 2&|."1 ])~
-------------------------------------------------------------------
Example: create a million random vectors in 3-space:
vv=. 1e6 3$ _1+2*rand 3e6 NB. rand=: [: ? ] # 0"_
and a million random unit vectors as rotation axes:
uu=. norm 1e6 3$ _1+2*rand 3e6
and also a million angles [-pi,pi] of rotation:
ww=. _1p1+2p1*rand 1e6
Then the rotated vectors rr are given by:
ts'rr=. vv qRot (uu;ww)'
0.249718 2.1811e8
Takes only 0.25 seconds on my Mac mini.
JVERSION
Engine: j804/j64/darwin
Release: commercial/2015-12-21 18:06:25
Library: 8.04.15
Qt IDE: 1.4.9/5.4.2
Platform: Darwin 64
Patrick
PS. Just tried J805 on the Mac mini running OS 10.11.5. With the
updated addon files, everything seems to work well. Thanks.
On Sun, 10 Jul 2016, Raul Miller wrote:
I need a routine which makes rotation matrices for a given angle.
For example, let's say that my angle is 0.05p1, I would be wanting
these two rotation matrices:
3 3$(2 1 o./ (,-)0.05p1) 0 4 1 3}&,=i.3
0.987688 0.156434 0
_0.156434 0.987688 0
0 0 1
and
3 3$(2 1 o./ (,-)0.05p1) 4 8 5 7}&,=i.3
1 0 0
0 0.987688 0.156434
0 _0.156434 0.987688
Now, obviously, I could implement this directly:
rotmat=:dyad define
3 3$(2 1 o./ (,-)y) (0 4 1 3+4*x)}&,=i.3
)
But it seems to me that there ought to be a better way of doing this.
And by better I mean more concise and direct.
But I'm not seeing that.
The best alternative I have thought of so far is:
elcric=:dyad define"0
if. 1<|y do.
(_2+|y) o. x**y
else.
y
end.
)
rotmat=:dyad define
(1 1-x) |. y elcric 1 0 0,0 4 3,:0 _3 4
)
And while maybe that satisfies some concept of "prettier" it is not
more concise and it is not more direct. It is not even faster.
That said, what I really want to build would be this:
rotate=:monad define
+/ .*/ 0 1 0 rotmat"0 y+0 0 0
)
(I threw in the unnecessary +0 0 0 to emphasize that I expect three angles.)
In other words, I have three different euler angles and I want the
rotation matrix they represent. So maybe there is even something
already implemented for this purpose? (But when I search jsoftware.com
for mentions of euler angles, I don't see anything promising.)
Any ideas?
Thanks,
--
Raul
P.S. I imagine I could live with getting the rotation quaternion they
represent, instead of the rotation matrix. But I have not investigated
the details of that approach here.
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm