I'm trying to create a 4D environment, similar to Miegakure's.
I'm having trouble understanding how to represent rotations. The creator of Miegakure wrote this small article explaining he made a class for 4d rotors. http://marctenbosch.com/news/2011/05/4d-rotations-and-the-4d-equivalent-of-quaternions/
How can I implement the functions of this class ? In particular the functions to rotate vectors and other rotors, and getting the inverse ?
I would appreciate some pseudocode examples. Thanks a lot to anyone who bothers answering.
I was able to use Rotors after learning more on the subject thanks to this youtube series about Geometric Algebra : https://www.youtube.com/watch?v=PNlgMPzj-7Q&list=PLpzmRsG7u_gqaTo_vEseQ7U8KFvtiJY4K
It's really well explained and I recommend it to whoever wants use geometric algebra.
If you already know about Quaternions multiplication, Rotor multiplication won't be any different, and the i, j, k units of quaternions are analog to the basis bivectors of Geometric Algebra : e12, e13, e23 (or e01, e02, e12)
So a Rotor in 4D will be (A + B*e12 + C*e13 + D*e14 + E*e23 + F*e24 + G*e34 + H*e1234).
A table showing how to multiply those units can be found on this page : http://www.euclideanspace.com/maths/algebra/clifford/d4/arithmetic/index.htm
To get the gist of it, consider the 2D Rotors.
They're of the form: R = A + B*e12
Now, if we compute product between 2 arbitrary rotors R_1 and R_2, we get:
R_1*R_2 = (
R_1.a * R_2.a
+ R_1.a * R_2.b*e12
+ R_1.b*e12 * R_2.a
+ R_1.b*e12 * R_2.b*e12 )
// but: e12*e12 = e1e2e1e2 = -e1e2e2e1= -e1e1 = -1
// this is confirmed by the computation rules I linked above
=
( (R_1.a * R_1.a - R_2.b * R_2.b)
+ (R_1.a * R_2.b + R_1.b * R_2.a) * e12 )
So in code, you would do something like :
R_3.a = R_1.a * R_2.a - R_1.b * R_2.b
R_3.b = R_1.a * R_2.b + R_1.b * R_2.a
Now it's only a matter of doing the same with those big 4D rotors, applying the multiplication rules for dimension 4 as linked above.
Here is the resulting code (using e0, e1, e2, e3 as basis vectors):
e: self.e*other.e - self.e01*other.e01 - self.e02*other.e02 - self.e03*other.e03 - self.e12*other.e12 - self.e13*other.e13 - self.e23*other.e23 + self.e0123*other.e0123,
e01: self.e*other.e01 + self.e01*other.e - self.e02*other.e12 - self.e03*other.e13 + self.e12*other.e02 + self.e13*other.e03 - self.e23*other.e0123 - self.e0123*other.e23,
e02: self.e*other.e02 + self.e01*other.e12 + self.e02*other.e - self.e03*other.e23 - self.e12*other.e01 + self.e13*other.e0123 + self.e23*other.e03 + self.e0123*other.e13,
e03: self.e*other.e03 + self.e01*other.e13 + self.e02*other.e23 + self.e03*other.e - self.e12*other.e0123 - self.e13*other.e01 - self.e23*other.e02 - self.e0123*other.e12,
e12: self.e*other.e12 - self.e01*other.e02 + self.e02*other.e01 - self.e03*other.e0123 + self.e12*other.e - self.e13*other.e23 + self.e23*other.e13 - self.e0123*other.e03,
e13: self.e*other.e13 - self.e01*other.e03 + self.e02*other.e0123 + self.e03*other.e01 + self.e12*other.e23 + self.e13*other.e - self.e23*other.e12 + self.e0123*other.e02,
e23: self.e*other.e23 - self.e01*other.e0123 - self.e02*other.e03 + self.e03*other.e02 - self.e12*other.e13 + self.e13*other.e12 + self.e23*other.e - self.e0123*other.e01,
e0123: self.e*other.e0123 + self.e01*other.e23 - self.e02*other.e13 + self.e03*other.e12 + self.e12*other.e03 - self.e13*other.e02 + self.e23*other.e01 + self.e0123*other.e,