dimforge / nalgebra

Linear algebra library for Rust.
https://nalgebra.org
Apache License 2.0
3.95k stars 471 forks source link

Add a dimension generic Rotor type #532

Open porky11 opened 5 years ago

porky11 commented 5 years ago

There are already dimension generic Vector types, but there's only a rotation type for 3D: the quaternion.

It's possible to implement general rotors.

3D rotors correspond to quaternions, 2D rotors correspond to complex numbers, and lower dimension rotors don't exist.

This would allow to represent rotations in higher dimensions and to generalize the rotations for writing dimension generic libraries like for physics.

Maybe implementing it requires implementing most of a geometric algebra, so it may be preferred to just implement geometric algebra in a more general way as an extra crate.

Ralith commented 5 years ago

I'd be very interested to see benchmarking against quaternions, too.

porky11 commented 5 years ago

@Ralith They (3D rotors and quaternions) are basically the same and when implementing it in an efficient way, there shouldn't be a difference in performance. You may want to look at other compile time geometric algebra libs, which use rotors, like versor or the library I wrote using scopes. (and when you want to use rust, there is an auto generated library for GA I wrote, which also supports rotors for up to 4 dimensions, but is not scalable, but not sure, if it's worth testing)

sebcrozet commented 5 years ago

@porky11 Was this closed intentionally? Given that we already define rotations based on quaternions and complex numbers, adding rotors would make sense too.

There are already dimension generic Vector types, but there's only a rotation type for 3D: the quaternion.

Here are the rotation types currently implemented in nalgebra:

porky11 commented 5 years ago

no, it was an accident. I'll look at the rotation and quaternion/complex types. I might try to implement general rotors myself; should still be less difficult than general geometric algebra. (even if just standard clifford) I hope, I understand typenum.

porky11 commented 5 years ago

I started work on implementing a rotor type but recognized a bunch of function, a Quaternion implements, are too difficult to implemnet for a general rotor. In some cases it's just more diffiuclt, but in other cases the logics are different. A general rotor cannot be represented as axis angle for example, but it could be represented by a set of scaled bivectors, which would require a bivector type. I'm not sure, if it's useful to implement a Rotor type, when no bivectors exist. And when adding bivectors I could also just add trivectors and whatever and almost have geometric algebra.

Ralith commented 5 years ago

Those would all be pretty neat to have, too!

porky11 commented 5 years ago

I think, when adding general rotors, general bivectors should be added as well. Adding these two types would already be a benefit for writing dimension generic code. Pseudo scalars or pseudo vectors are probably not required for most operations. Simple vectors and scalars and extra methods are enough to replace them.

Bivectors allow storing the torque in a dimension generic way: Bivec<T, U2> is represented by a single element array, so basically a T, as you would in 2D, Bivec<T, U3> is represented as a 3 element array, basically the scaled rotation axis vector, as you would represent torque in 3d.

I think, that's a good tradeoff between implementing a full GA lib, which semes not to be possible without const generics, using different types depending on dimension.

entropylost commented 3 years ago

I would also find geometric algebra nice, although it isn't absolutely necessary.

entropylost commented 3 years ago

Edit: Trying to make a game with 4 dimensions and rotors would be really helpful as otherwise I have to use rotation matricies.

porky11 commented 3 years ago

@iMplode-nZ I also think, GA would be better, but for GA, it's probably best to create a new library. But in current rust it's not possible or at least difficult to implement full GA at compiletime.

You could either use a dynamically typed implementation with a single GA multivector type, or implement dimension generic versions of specific vector types (with at least Vectors, Bivectors, Rotors), or implement a specific GA for 4D.

I recently wrote a bunch of traits and don't use specific implementations of vector math in my libraries, so most of my math code just works, when I change the dimension. It's a bit more difficult in the first place, since you can't use vector components or dimension specific functions (cross product) to get a working code, but it will always be dimension generic. For 4D, you could use my 2D implementation of GA as a base.

entropylost commented 3 years ago

I actually just used rotation matricies.

I think it's guaranteed possible to implement GA at compile time as Rust's compiler is turing complete.

porky11 commented 3 years ago

At least not yet using const generics. I don't think it's reasonable to implement it using typenum, nor would it be usable.

entropylost commented 3 years ago

Yeah... it would have to be recursive. Eg:

trait Rotor {
  type Size: Num;
  type T;
}
struct RCons<S: Num, T, H: Rotor<T = T, Size: S::OneLess>>(S::NArray<T>, H);
impl Rotor for RCons { ... }
struct RNil;
impl Rotor for RNil { ... }
F0Xde commented 3 years ago

Just to have it mentioned, ultraviolet uses rotors and contains all the derivations the author did.

jsmith628 commented 2 years ago

I know this is a little old, but I think I can add a couple things:

First off, I don't really think adding only rotors would make much sense. The fact of the matter is that there already is a generalized rotation type in nalgebra: Rotation<T,N>

Now, I am definitely a huge fan of geometric algebra, but I don't really see much reason why we'd want to use Rotors over Matrices in this context. I mean, for sure quaternions and complex numbers are much better than matrices in 2D and 3D, but the primary reason for that is their lower memory footprint, ease of interpolation, and stability, which just kinda stops being the case after around 5D or 6D. The number of components in a Rotor is 2n-1 and surpasses matrices at 6D. And AFAIK, there isn't really a good algorithm for interpolation of rotors in general. I know of one for 4D and 5D, but beyond that, I actually haven't seen any in any literature that I've read. Whereas for Matrices, you can definitely get something working using block diagonalization or matrix logs/exp etc. (though, perhaps rotors are still more numerically stable at these dimension, I haven't really tested that)

Now that being said, I do still very much like using Geometric Algebra, and usually prefer it to matrices since I mostly work in 2D-4D, but I think to justify it being in nalgebra, as @porky11 says you'd want to also add Bivectors. Everyone likes to talk about the rotations in GA, but I think a huge unsung benefit of GA are blades/n-vectors and their ability to represent oriented vector-spaces. Meaning that adding bivectors would be quite useful, since they'd allow you to represent planes and rotation planes, something that really isn't in nalgebra yet.

But then again, we could also achieve the same effect by implementing a special SkewSymmetric type instead. Skew-symmetric matrices are mathematically the same as bivectors in a lot of ways, so they may be the better choice to avoid all the extra hassle with generics GA would cause, albeit while using a little over double the memory.

@porky11

I think, that's a good tradeoff between implementing a full GA lib, which semes not to be possible without const generics, using different types depending on dimension.

At least not yet using const generics. I don't think it's reasonable to implement it using typenum, nor would it be usable.

Nah, it's totally possible. I'd definitely agree that if it were made perfectly generic using typenum, it'd be kinda horrid to use, but If you allow yourself to enumerate a couple trait impls (kinda like nalgebra does pretty reasonably with ToTypenum and ToConst), you can very much get a generic GA library and can make it quite pretty at that.

In fact, if you forgive me for a little self-promotion, I've actually made it if you'd like to check it out.

porky11 commented 2 years ago

@jsmith628 Thanks for your "little self-promotion". I'll definitely have a look at it.