Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Matrix translation / rotation? #1160

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

Matrix translation / rotation? #1160

aneilbaboo opened this issue Jul 9, 2018 · 17 comments

Comments

@aneilbaboo
Copy link

@aneilbaboo aneilbaboo commented Jul 9, 2018

What is the right way to translate or rotate a sparse or dense matrix?

@josdejong
Copy link
Owner

@josdejong 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
Copy link
Collaborator

@ericman314 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
Copy link
Author

@aneilbaboo aneilbaboo commented Jul 9, 2018

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

@josdejong
Copy link
Owner

@josdejong josdejong commented Jul 10, 2018

Ah, of course. Sounds cool!

@YuvalGat
Copy link

@YuvalGat YuvalGat commented Oct 21, 2018

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
Copy link
Collaborator

@ericman314 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
Copy link
Owner

@josdejong 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
Copy link
Contributor

@ChristopherChudzicki ChristopherChudzicki commented Oct 22, 2018

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]).

Edit: Mathematica Documentation for RotationMatrix

@YuvalGat
Copy link

@YuvalGat 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
Copy link
Contributor

@rnd-debug 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
Copy link
Owner

@josdejong 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
Copy link
Contributor

@rnd-debug rnd-debug commented Oct 3, 2020

@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
Copy link
Owner

@josdejong josdejong commented Oct 3, 2020

Are there any downsides of using coefficient-wise?

@rnd-debug
Copy link
Contributor

@rnd-debug rnd-debug commented Oct 3, 2020

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

@josdejong
Copy link
Owner

@josdejong josdejong commented Oct 3, 2020

👍

@rnd-debug rnd-debug mentioned this issue Oct 3, 2020
5 tasks
@josdejong
Copy link
Owner

@josdejong 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.

@josdejong
Copy link
Owner

@josdejong josdejong commented Nov 2, 2020

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants