{{ message }}
/ mathjs Public

# Matrix translation / rotation?#1160

Closed
opened this issue Jul 9, 2018 · 17 comments
Closed

# Matrix translation / rotation?#1160

opened this issue Jul 9, 2018 · 17 comments
Labels

### aneilbaboo commented Jul 9, 2018

 What is the right way to translate or rotate a sparse or dense matrix? The text was updated successfully, but these errors were encountered:

### josdejong commented Jul 9, 2018

 Right now there is only `transpose` and `ctranspose`. A translate/rotate function sounds interesting, we don't have that in mathjs. I guess we can get inspiration from similar functions in python/matlab/etc. Do you have some concrete use cases for rotating a matrix?

### ericman314 commented Jul 9, 2018

 Typically rotation matrices are used to manipulate points or objects in space or on the plane, for example when doing 3D graphics. The matrix is constructed using trig functions, then multiplied to each vector in the object to be rotated. This allows for rotation of many points at a time. It would be very handy to have a set of functions to create rotation matrices. Or possibly @aneilbaboo means to rotate the elements themselves within a square matrix or something. I'm not familiar with the applications of doing that.

### aneilbaboo commented Jul 9, 2018

 Thanks, @ericman314 - yes, that is what I meant.

### josdejong commented Jul 10, 2018

 Ah, of course. Sounds cool!

### YuvalGat commented Oct 21, 2018 • edited

 I think I could work on this. How about the following syntax? ```const vec = [1, 2]; const rotatedVec = math.rotate(vec, math.pi / 4); // [-0.707..., 2.12...]``` I could also do this for 3D vectors (perhaps even n-dimensional?)

### ericman314 commented Oct 22, 2018

 Could there also be a function that returns a rotation matrix? Then you could do the trig just once and rotate lots of vectors quickly: ```const vec = [1, 2]; const rotationMat = math.rotationMatrix(math.pi / 4); // [[0.707, -0.707], [0.707, 0.707]] const rotatedVec = math.multiply(rotationMat, vec); // [-0.707, 2.12]``` I think 3D rotations are also a must-have, but I don't know about n-dimensional. I can't wrap my head around that!

### josdejong commented Oct 22, 2018

 I think I could work on this. Thanks for your offer @YuvalGat, that's great! I like the idea of @ericman314 , so that means we will create two new functions, where `math.rotate` is simply eye candy for `math.multiply(vec, math.rotationMatrix(angle))`. I also guess we need support for both 2D and 3D matrices? The function `math.rotate` can automatically detect this, but the functions `math.rotationMatrix` not. Maybe create two versions of the function: `math.rotationMatrix2D` and `math.rotationMatrix3D`? Are there any lessons we can learn for the API from other languages/libraries?

### ChristopherChudzicki commented Oct 22, 2018 • edited

 I think that both `rotate` and `rotationMatrix` can infer the correct dimensionality. My suggestion would be to have function signatures similar to Mathematica: `rotationMatrix(theta)`: returns a 2d rotation matrix for counter-clockwise rotation by angle `theta`. `rotationMatrix(theta, v)`: returns a rotation matrix for rotation by angle `theta` (in positive sense) around vector `v`. The dimensionality is inferred from `v`. "Positive sense" is probably rigorously defined in terms of some right-hand rule, at least for 3d. Example: `rotationMatrix(theta, [0, 0, 1]) = - rotationMatrix(-theta, [0, 0, -1])`. And: `rotate(w, theta)`: alias for `multiply(rotationMatrix(theta), w)` `rotate(w, theta, v)`: alias for `multiply(rotationMatrix(theta, v), w)` If it became useful, the above syntax could be extended to dimensions greater than 3. But in dimensions greater than 3 I do not believe there is the idea of a rotation axis, instead one speaks of "rotation plane". (Only in 3d is there a natural correspondence between rotation plane and rotation axis.) So in higher dimensions, `rotationMatrix(theta, [v1, v2])`.

### YuvalGat commented Oct 22, 2018

 This sounds like a good idea! I'll get working ASAP. I'll submit a PR when I have the basic 2D behaviour working properly. Still reading the code to understand how everything works, I believe I'll get it done within the next couple of days.

### rnd-debug commented Sep 28, 2020

 @josdejong How dead is this issue? Looks like @YuvalGat gave up (?) and the basic `rotationMatrix(theta)` seems to be easy enough for me :)

### josdejong commented Sep 30, 2020

 I think Yuval didn't manage to find time for it. Would be great if you can pick it up @rnd-debug, thanks!

### rnd-debug commented Oct 3, 2020 • edited

 @josdejong ok, work started. Short question: in case of `rotate(theta, v)`, we can calculate the rotation matrix: coefficient-wise by manually calculating every coefficient. Like `R = [[ cos + vx*vx*(1-cos), etc.] etc.] ` => more wordy. OR by using the "Rodrigues' rotation formula" : `R = I + sin.K + (1-cos).K^2` => more mathjs dependencies need to be included (matrix multiplication, addition, identity). Probably slower and more prone to rounding issues. What would be preferable? I am tending towards coefficient-wise as more standalone solution. Using this as reference.

### josdejong commented Oct 3, 2020

 Are there any downsides of using coefficient-wise?

### rnd-debug commented Oct 3, 2020

 Overhead with typing the coefficients. :D so let's go for coefficient-wise.

### josdejong commented Oct 3, 2020

 👍

mentioned this issue Oct 3, 2020

### josdejong commented Oct 7, 2020

 Function `rotationMatrix` is now available in `v7.4.0`, and @rnd-debug plans on creating `rotate` on top of that next. Let's keep this issue open until then.

mentioned this issue Oct 10, 2020

### josdejong commented Nov 2, 2020

 The new function `rotate` is now available in `v7.6.0`. Thanks again @rnd-debug . Closing this issue now.