eโโ is orthogonal to Z eโโ
eโโ is orthogonal to X eโโ(!)
eโโ is orthogonal to Y eโโ
eโโ eโโ = eโโโโ eโโ eโโ = eโโโโ = -eโโโโ = eโโโโ eโโ eโโ = eโโโโ = -eโโโโ = eโโโโ
all have ring 1-2-3-4-1...
eโ โง eโโโ = +eโโโโ 0 swaps
eโ โง eโโโ = -eโโโโ 1 swap
eโ โง eโโโ = +eโโโโ 2 swaps
eโ โง eโโโ = -eโโโโ 3 swaps
all good hypervolumes. These need to alternate similar to how a 2D face needs to be of alternating orientation at the face edges in 3D.
Doing vR then Rฬ(vR) sounds tedious? It is!
v = vโeโ vโeโ vโeโ vโeโ
B = R[1]eโโ + R[2]eโโ + R[3]eโโ + R[4]eโโ + R[5]eโโ + R[6]eโโ
I = R[7]eโโโโ
s = R[0]
RฬvR = (s - B + I) v (s + B + I)
Now you can group s + I to term lets say J
RฬvR = (J - B) v (J + B)
You can do that because in Addition you can shuffle around, you only need to consider commutativity in multiplication
Next move was new to me
RฬvR = (Jv - Bv) (J + B)
That's distributivity and to the left and its ok because we put the v AFTER those terms
Now lets expand that, then tackle one by one
RฬvR = JvJ + JvB - BvJ - BvB
JvJ
Jv = (s + I)v = sv + Iv
JvJ is thus (sv + Iv) * (s + I) and thats svs + svI + Ivs + IvI
as I anticommutes with vectors putting -vII makes that -vIยฒ
I stumbled here but you can see any odd and grade 4 will anticommute even will commute if you do it on paper as an exercise. eโ eโโโโ or eโโ eโโโ or eโ eโโโ or eโโ eโโ
so
svs + svI + Ivs - vIยฒ
s is a scalar so we can do svI + sIv then svI - svI
leaves sยฒv - vIยฒ which can be distributed to (sยฒ - Iยฒ)v
JvB - BvJ
A mathmatician will see this can be done together as 3 terms are the same so lets do them in one go
JvB - BvJ
= (s + I)vB - Bv(s + I)
expand
= svB + IvB - Bvs - BvI
we now want s and I grouped out. Remember s commutes with anything and I and B are both even graded so they commute with each other and s ofc. But v is grade 1 so moving it will flip signs of B or I
So you reorder first and in case you did not know, over addition the terms always commute
= svB - Bvs + IvB - BvI
// remember v is grade one and B and I will commute so -BvI = BIv = IBv
= s(vB - Bv) + I(vB + Bv)
I will admit i know nothing much about all of these tricks but still do all by hand. So i got hinted now these include the standard GA identities:
vB - Bv = 2(v ยท B)
vB + Bv = 2(v โง B)
So far I can tell from Doran Chapter 2 you can do two vectors(! grade 1 !) a and b like
ba = b ยท a + b โง a = a ยท b - a โง b
so now when you do ab + ba you get twice the dot product but due to anticommutivity of the wedge the wedge will cancel out
ab + ba = 2 a ยท b !
and for ab - ba now your dot product comes to 0 while the wedge will double (as its - - so +)
ab - ba = 2 a โง b
But we dont deal with grade 1 vectors here where eโ and eโ etc would anticommute. B and v are grade 2 and 1 though so when you have v and B now
vB = v ยท B + v โง B
when you reorder these to Bv the sign of the wedge product will not change. eโ โง eโโ and eโโ โง eโ are the same!
eโ eโโ = eโโโ
eโโ eโ = eโโโ = -eโโโ = eโโโ
However ... the dot product will now sign flip and cancel out :D Why? See that a plane and a vector will not dot like 2 vectors
v ยท B = eโ ยท (eโ โง eโ)
The reason is not explained in Hollmeier and noted its the "hodge adjoint"
but it turns out you can derive the hack of "bringing the same basis close at the paranthesis" with known geometric product rules:
Because the dot product is defined to LOWER any geometric product by the amount these 2 differ in their grade
Aแตฃ ยท Bโ = โจAแตฃBโโฉ(|r-s|)
Imagine B ยท v
B ยท v = (eโ eโ) ยท eโ
when you dot two vectors you want to measure how much they overlap and 2 orthogonal bases eโ eโ will always be 0 and the same eโยฒ is always 1. But that's just telling you how much eโ overlaps with eโ. When you want to know how much a line eโ overlaps with an area/plane eโโ you will get back the other line that makes that area. But direction matters now. Because (eโ eโ) ยท eโ leaves you -eโ and eโ ยท (eโ eโ) leaves you eโ!
When you know or think about or test some
Aแตฃ ยท Bโ = โจAแตฃBโโฉ(|r-s|)
you will understand that and how this works.
e3 ยท eโ โง eโ
thats just eโ (eโeโ) and we want all grade 1 parts. what are they?
e3 ยท e1 ยท e2 thats a scalar and its 0. none overlap!
e3 โง eโ โง eโ = eโ โง eโ โง eโ
problem is ... these are only grade 0 and 3 - so the result is zero.
eโโ ยท (eโโโ)
that is
eโโโโโ so thats just eโ left you can spare the rest
leaves
eโโ ยท (eโโโ) = eโ
try the other way
eโโ ยท (eโโโ) = eโโโโโ = -eโ
very simple example
eโ ยท (eโ โง eโ) = โจeโโโ = -eโโโ = -eโโฉ(1) = -eโ
vB - Bv = 2(v ยท B)
vB + Bv = 2(v โง B)
so to prove this is correct lets see for vB + Bv
vB = v ยท B + v โง B
Bv = B ยท v + B โง v
so we know the wedges commute as these are known grade 2 bivectors and v is grade 1
f.e. eโ โง eโโ and eโโ โง eโ seem eโโโ and eโโโ thats 2 swaps. They commute
and the dot products give
v ยท B that will be some grade 1 vector left
B ยท v that will be the same grade 1 but negated
so it makes sense we get that twice on vB - Bv and none on vB + Bv
and as B โง v == v โง B it makes sense they go twice on vB + Bv and 0 on vB - Bv
so we are at
(sยฒ - Iยฒ)v + (s(vB - Bv) + I(vB + Bv)) - BvB
Ok so as departure is getting closer ill short this one a bit
we know
vB - Bv = 2(v ยท B)
so
vB = 2(v ยท B) + Bv
2(v ยท B)
vB - 2(v ยท B) = Bv
flip
Bv = vB - 2(v ยท B)
Now add B to the right
BvB = vBยฒ - 2(v ยท B)B
Minus
-BvB = - vBยฒ + 2(v ยท B) B
-BvB = 2(v ยท B)B - vBยฒ
(sยฒ - Iยฒ)v + s(vB - Bv) + I(vB + Bv) + 2(v ยท B)B - vBยฒ
puh
Remember
vB - Bv = 2(v ยท B)
vB + Bv = 2(v โง B)
So
(sยฒ - Iยฒ)v + 2s(v ยท B) + 2I(v โง B) + 2(v ยท B)B - vBยฒ
2(v ยท B)B will give 1-vectors (v ยท B) but with โง B also when eโ โง eโโ is lin. independent a trivector
Now this trivector will cancel out with whatever comes from vBยฒ
- Bยฒ has quadvector in its results. eโโ * eโโ = eโโ but eโโ * eโโ = eโโโโ
-(Bโโยฒ + Bโโยฒ + Bโโยฒ + Bโโยฒ + Bโโยฒ + Bโโยฒ) + 2(BโโBโโ + BโโBโโ + BโโBโโ)I
when you multiply this with a vector this will return the same 3 trivectors
So the quadvector from Bยฒ will cancel out by going to trivectors with v while the trivectors that cancel these come from wedging grade 1 with grade 2 so trivectors again in the first part 2(v ยท B)B
Means -BvB will always be a vector so we could do either
โจ-BvBโฉโ = โจ2(v ยท B)Bโฉโ - vโจBยฒโฉโ
This means take only grade 1 (from 1 + 3) then minus vector * grade 0 (vector again grade 1) from grade 1 + 3
=> leaves only grade 1 vector part
also correct is to use ยท not ร as this will only return ther grade 1 dot product (see above)
โจ-BvBโฉโ = (2(v ยท B) ยท B) - vโจBยฒโฉโ
Caution here. when you square B that will always introduce a minus as all planes square to -1 and we only want the scalar part
So
- vโจBยฒโฉโ == -v (- |B|ยฒ) == |B|ยฒv
As we later want to know the planes we can IN THIS CASE NOT IN STA short to
(sยฒ - Iยฒ)v - vBยฒ == v(sยฒ - Iยฒ + โจBยฒโฉโ)
Bยฒ is thus -(Bโโยฒ + Bโโยฒ + Bโโยฒ + Bโโยฒ + Bโโยฒ + Bโโยฒ) + 2(BโโBโโ + BโโBโโ + BโโBโโ)I (grade 4) + all other mixed terms cancel out
- Pairs sharing an axis anticommute and cancel (eโโeโโ + eโโeโโ = 0)
- orthogonal pairs commute and form the quadvector (2(BโโBโโ + BโโBโโ + BโโBโโ)I)
Ok so have this now as a usable vector multiplication function Rotor4.rotateVector4(v)
Easy parts
s = R[0]
p = R[7]
Bivector parts
Bโโ = R[1]
Bโโ = R[2]
Bโโ = R[3]
Bโโ = R[4]
Bโโ = R[5]
Bโโ = R[6]
Squares makes it easier and faster
s_2 = sยฒ
xy_2 = Bโโยฒ
yz_2 = Bโโยฒ
zx_2 = Bโโยฒ
zw_2 = Bโโยฒ
xw_2 = Bโโยฒ
yw_2 = Bโโยฒ
p_2 = Iยฒ
We set v = eโ, start on v(sยฒ - Iยฒ + โจBยฒโฉโ)
v' = (sยฒ - pยฒ + Bโโยฒ + Bโโยฒ + Bโโยฒ + Bโโยฒ + Bโโยฒ + Bโโยฒ) eโ
+ ...
dot all bivectors with eโ for 2s(v ยท B). gives
eโ ยท Bโโeโโ = +Bโโeโ
eโ ยท Bโโeโโ = -Bโโeโ
eโ ยท Bโโeโโ = +Bโโeโ
The other 3 bivectors/planes have no eโ in them, thus will be 0
v' = (sยฒ - pยฒ + Bโโยฒ + Bโโยฒ + Bโโยฒ + Bโโยฒ + Bโโยฒ + Bโโยฒ) eโ
+ 2 * s * (Bโโeโ - Bโโeโ + Bโโeโ)
+ ...
wedge all bivectors with eโ for 2I(v โง B) AND multiplying by I from the left !! gives
eโโโโ * (eโ โง Bโโeโโ) = eโโโโ * Bโโeโโโ = Bโโ eโโโโโโโ = -eโโโโโโโ = eโโโโโโโ = -eโโโโโ = eโโโโโ = -eโโโ = Bโโeโ
eโโโโ * (eโ โง Bโโeโโ) = eโโโโ * Bโโeโโโ = Bโโ eโโโโโโโ = -eโโโโโโโ = eโโโโโ = -eโโโโโ = eโโโ = -Bโโeโ
eโโโโ * (eโ โง Bโโeโโ) = eโโโโ * Bโโeโโโ = Bโโ eโโโโโโโ = -eโโโโโโโ = eโโโโโ = -eโโโ = Bโโeโ
We still need to multiply by the pseudoscalars scalar component which ill just use p so you know its p times I
The other 3 planes/bivectors have eโ in them, thus the wedge will be 0.
v' = (sยฒ - pยฒ + Bโโยฒ + Bโโยฒ + Bโโยฒ + Bโโยฒ + Bโโยฒ + Bโโยฒ) eโ
+ 2 * s * (Bโโeโ - Bโโeโ + Bโโeโ)
+ 2 * p * (Bโโeโ - Bโโeโ + Bโโeโ)
+ ...
Last term is 2(v ยท B) ยท B
We already know v ยท B is Bโโeโ - Bโโeโ + Bโโeโ
Now this is a vector and we know its components eโ eโ eโ will have dot 0 with all planes that are not that basis vector
another dot of this vector with B gives
(Bโโeโ - Bโโeโ + Bโโeโ) ยท (Bโโeโโ + Bโโeโโ + Bโโeโโ + Bโโeโโ + Bโโeโโ + Bโโeโโ)
= -Bโโยฒeโ + BโโBโโeโ + 0 + 0 + 0 + BโโBโโeโ
+ 0 + BโโBโโeโ - Bโโยฒeโ -BโโBโโeโ - 0 - 0
+ 0 + 0 + 0 - BโโBโโeโ - Bโโยฒeโ - BโโBโโeโ
= -Bโโยฒeโ + BโโBโโeโ + BโโBโโeโ + BโโBโโeโ - Bโโยฒeโ -BโโBโโeโ - BโโBโโeโ - Bโโยฒeโ - BโโBโโeโ
Now don't forget it's 2(v ยท B) ยท B so 2 *
2 * (-Bโโยฒeโ + BโโBโโeโ + BโโBโโeโ + BโโBโโeโ - Bโโยฒeโ -BโโBโโeโ - BโโBโโeโ - Bโโยฒeโ - BโโBโโeโ)
v' = (sยฒ - pยฒ + Bโโยฒ + Bโโยฒ + Bโโยฒ + Bโโยฒ + Bโโยฒ + Bโโยฒ) eโ
+ 2 * s * (Bโโeโ - Bโโeโ + Bโโeโ)
+ 2 * p * (Bโโeโ - Bโโeโ + Bโโeโ)
+ 2 * (-Bโโยฒeโ + BโโBโโeโ + BโโBโโeโ + BโโBโโeโ - Bโโยฒeโ -BโโBโโeโ - BโโBโโeโ - Bโโยฒeโ - BโโBโโeโ)
This would already work ... but we can simplify this ofc
eโ Parts
(sยฒ - pยฒ + Bโโยฒ + Bโโยฒ + Bโโยฒ + Bโโยฒ + Bโโยฒ + Bโโยฒ) eโ
2 * (-Bโโยฒeโ - Bโโยฒeโ - Bโโยฒeโ)
= (sยฒ - pยฒ - Bโโยฒ + Bโโยฒ - Bโโยฒ + Bโโยฒ - Bโโยฒ + Bโโยฒ) eโ
eโ Parts
2 * s * Bโโeโ
2 * p * Bโโeโ
2 * (BโโBโโeโ - BโโBโโeโ)
= 2 * (s * Bโโ + p * Bโโ + BโโBโโ - BโโBโโ) eโ
eโ Parts
2 * s * -Bโโeโ
2 * p * -Bโโeโ
2 * (BโโBโโeโ - BโโBโโeโ)
= 2 * (s * -Bโโ + p * -Bโโ + BโโBโโ - BโโBโโ) eโ
eโ Parts
2 * s * Bโโeโ
2 * p * Bโโeโ
2 * (BโโBโโeโ - BโโBโโeโ)
= 2 (s * Bโโ + p * Bโโ + BโโBโโ - BโโBโโ) eโ
not bad!
= (sยฒ - pยฒ - Bโโยฒ + Bโโยฒ - Bโโยฒ + Bโโยฒ - Bโโยฒ + Bโโยฒ) eโ
+ 2 * (s * Bโโ + p * Bโโ + BโโBโโ - BโโBโโ) eโ
+ 2 * (s * -Bโโ + p * -Bโโ + BโโBโโ - BโโBโโ) eโ
+ 2 (s * Bโโ + p * Bโโ + BโโBโโ - BโโBโโ) eโ
Ok so now i have to admit thats actually only the COLUMNS so this is not part vโ, vโ, etc. but actually go there so that's one part of each!
v'โ = (sยฒ - pยฒ - Bโโยฒ + Bโโยฒ - Bโโยฒ + Bโโยฒ - Bโโยฒ + Bโโยฒ) * vโ + ... vโ + ... vโ + ... vโ
v'โ = 2 * (s * Bโโ + p * Bโโ + BโโBโโ - BโโBโโ) * vโ + ... vโ + ... vโ + ... vโ
v'โ = 2 * (s * -Bโโ + p * -Bโโ + BโโBโโ - BโโBโโ) * vโ + ... vโ + ... vโ + ... vโ
v'โ = 2 (s * Bโโ + p * Bโโ + BโโBโโ - BโโBโโ) * vโ + ... vโ + ... vโ + ... vโ
v(sยฒ - Iยฒ + Bยฒ) v' = (sยฒ - pยฒ + Bโโยฒ + Bโโยฒ + Bโโยฒ + Bโโยฒ + Bโโยฒ + Bโโยฒ) eโ
+ ...
2s(v ยท B) eโ ยท Bโโeโโ = -Bโโeโ
eโ ยท Bโโeโโ = Bโโeโ
eโ ยท Bโโeโโ = Bโโeโ
=> 2 * s * (-Bโโeโ + Bโโeโ + Bโโeโ)
2I(v โง B) eโโโโ * (eโ โง Bโโeโโ) = ... eโโโโโโโ = -eโโโโโโโ = eโโโโโ = -eโโโ = Bโโeโ
eโโโโ * (eโ โง Bโโeโโ) = ... eโโโโโโโ = -eโโโโโโโ = eโโโโโ = -Bโโeโ
eโโโโ * (eโ โง Bโโeโโ) = ... eโโโโโโโ = -eโโโโโโโ = eโโโโโ = -eโโโ = Bโโeโ
=> 2 * p * (Bโโeโ - Bโโeโ + Bโโeโ)
2(v ยท B) ยท B (-Bโโeโ + Bโโeโ + Bโโeโ) ยท (Bโโeโโ + Bโโeโโ + Bโโeโโ + Bโโeโโ + Bโโeโโ + Bโโeโโ)
= -Bโโยฒeโ + 0 + BโโBโโeโ + 0 - BโโBโโeโ + 0
+ 0 - Bโโยฒeโ + BโโBโโeโ + BโโBโโeโ + 0 + 0
+ 0 + 0 + 0 - BโโBโโeโ - BโโBโโeโ - Bโโยฒeโ
=> 2 * (-Bโโยฒeโ + BโโBโโeโ - BโโBโโeโ - Bโโยฒeโ + BโโBโโeโ + BโโBโโeโ - BโโBโโeโ - BโโBโโeโ - Bโโยฒeโ)
v' = (sยฒ - pยฒ + Bโโยฒ + Bโโยฒ + Bโโยฒ + Bโโยฒ + Bโโยฒ + Bโโยฒ) eโ
+ 2 * s * (-Bโโeโ + Bโโeโ + Bโโeโ)
+ 2 * p * (Bโโeโ - Bโโeโ + Bโโeโ)
+ 2 * (-Bโโยฒeโ + BโโBโโeโ - BโโBโโeโ - Bโโยฒeโ + BโโBโโeโ + BโโBโโeโ - BโโBโโeโ - BโโBโโeโ - Bโโยฒeโ)
eโ Parts
(sยฒ - pยฒ - Bโโยฒ - Bโโยฒ + Bโโยฒ + Bโโยฒ + Bโโยฒ - Bโโยฒ) eโ
eโ Parts
2 * (s * -Bโโ + p * -Bโโ + BโโBโโ - BโโBโโ) eโ
eโ Parts
2 * (s * Bโโ + p * Bโโ + BโโBโโ - BโโBโโ) eโ
eโ Parts
2 * (s * Bโโ + p * Bโโ - BโโBโโ + BโโBโโ) eโ
v'โ = (sยฒ - pยฒ - Bโโยฒ + Bโโยฒ - Bโโยฒ + Bโโยฒ - Bโโยฒ + Bโโยฒ) * vโ
+ 2 * (s * -Bโโ + p * -Bโโ + BโโBโโ - BโโBโโ) * vโ
+
+
v'โ = 2 * (s * Bโโ + p * Bโโ + BโโBโโ - BโโBโโ) * vโ
+ (sยฒ - pยฒ - Bโโยฒ - Bโโยฒ + Bโโยฒ + Bโโยฒ + Bโโยฒ - Bโโยฒ) * vโ
+
+
v'โ = 2 * (s * -Bโโ + p * -Bโโ + BโโBโโ - BโโBโโ) * vโ
+ 2 * (s * Bโโ + p * Bโโ + BโโBโโ - BโโBโโ) * vโ
+
+
v'โ = 2 (s * Bโโ + p * Bโโ + BโโBโโ - BโโBโโ) * vโ
+ 2 * (s * Bโโ + p * Bโโ - BโโBโโ + BโโBโโ) * vโ
+
+
v(sยฒ - Iยฒ + Bยฒ) v' = (sยฒ - pยฒ + Bโโยฒ + Bโโยฒ + Bโโยฒ + Bโโยฒ + Bโโยฒ + Bโโยฒ) eโ
+ ...
2s(v ยท B) eโ ยท Bโโeโโ = -Bโโeโ
eโ ยท Bโโeโโ = Bโโeโ
eโ ยท Bโโeโโ = Bโโeโ
=> 2 * s * (-Bโโeโ + Bโโeโ + Bโโeโ)
2I(v โง B) eโโโโ * (eโ โง Bโโeโโ) = eโโโโโโโ = -eโโโโโ = eโโโโโ = -eโโโ = Bโโeโ
eโโโโ * (eโ โง Bโโeโโ) = eโโโโโโโ = -eโโโโโ = eโโโ = -Bโโeโ
eโโโโ * (eโ โง Bโโeโโ) = eโโโโโโโ = -eโโโโโ = Bโโeโ
=> 2 * p * (Bโโeโ - Bโโeโ + Bโโeโ)
2(v ยท B) ยท B (-Bโโeโ + Bโโeโ + Bโโeโ) ยท (Bโโeโโ + Bโโeโโ + Bโโeโโ + Bโโeโโ + Bโโeโโ + Bโโeโโ)
= BโโBโโeโ - Bโโยฒeโ + 0 + 0 + 0 - BโโBโโeโ
+ BโโBโโeโ + 0 - Bโโยฒeโ + 0 + BโโBโโeโ + 0
+ 0 + 0 + 0 - Bโโยฒeโ - BโโBโโeโ - BโโBโโeโ
=> 2 * (BโโBโโeโ - Bโโยฒeโ - BโโBโโeโ + BโโBโโeโ - Bโโยฒeโ + BโโBโโeโ - Bโโยฒeโ - BโโBโโeโ - BโโBโโeโ)
v' = (sยฒ - pยฒ + Bโโยฒ + Bโโยฒ + Bโโยฒ + Bโโยฒ + Bโโยฒ + Bโโยฒ) eโ
+ 2 * s * (-Bโโeโ + Bโโeโ + Bโโeโ)
+ 2 * p * (Bโโeโ - Bโโeโ + Bโโeโ)
+ 2 * (BโโBโโeโ - Bโโยฒeโ - BโโBโโeโ + BโโBโโeโ - Bโโยฒeโ + BโโBโโeโ - Bโโยฒeโ - BโโBโโeโ - BโโBโโeโ)
eโ Parts
(sยฒ - pยฒ + Bโโยฒ - Bโโยฒ - Bโโยฒ - Bโโยฒ + Bโโยฒ + Bโโยฒ) eโ
eโ Parts
2 * (s * Bโโ + p * Bโโ + BโโBโโ - BโโBโโ) eโ
eโ Parts
2 * (s * -Bโโ + p * -Bโโ + BโโBโโ - BโโBโโ) eโ
eโ Parts
2 * (s * Bโโ + p * Bโโ - BโโBโโ + BโโBโโ) eโ
v'โ = (sยฒ - pยฒ - Bโโยฒ + Bโโยฒ - Bโโยฒ + Bโโยฒ - Bโโยฒ + Bโโยฒ) * vโ
+ 2 * (s * -Bโโ + p * -Bโโ + BโโBโโ - BโโBโโ) * vโ
+ 2 * (s * Bโโ + p * Bโโ + BโโBโโ - BโโBโโ) * vโ
+
v'โ = 2 * (s * Bโโ + p * Bโโ + BโโBโโ - BโโBโโ) * vโ
+ (sยฒ - pยฒ - Bโโยฒ - Bโโยฒ + Bโโยฒ + Bโโยฒ + Bโโยฒ - Bโโยฒ) * vโ
+ 2 * (s * -Bโโ + p * -Bโโ + BโโBโโ - BโโBโโ) * vโ
+
v'โ = 2 * (s * -Bโโ + p * -Bโโ + BโโBโโ - BโโBโโ) * vโ
+ 2 * (s * Bโโ + p * Bโโ + BโโBโโ - BโโBโโ) * vโ
+ (sยฒ - pยฒ + Bโโยฒ - Bโโยฒ - Bโโยฒ - Bโโยฒ + Bโโยฒ + Bโโยฒ) * vโ
+
v'โ = 2 (s * Bโโ + p * Bโโ + BโโBโโ - BโโBโโ) * vโ
+ 2 * (s * Bโโ + p * Bโโ - BโโBโโ + BโโBโโ) * vโ
+ 2 * (s * Bโโ + p * Bโโ - BโโBโโ + BโโBโโ) * vโ
+
v(sยฒ - Iยฒ + Bยฒ) v' = (sยฒ - pยฒ + Bโโยฒ + Bโโยฒ + Bโโยฒ + Bโโยฒ + Bโโยฒ + Bโโยฒ) eโ
+ ...
2s(v ยท B) eโ ยท Bโโeโโ = -Bโโeโ
eโ ยท Bโโeโโ = -Bโโeโ
eโ ยท Bโโeโโ = -Bโโeโ
=> 2 * s * (-Bโโeโ -Bโโeโ -Bโโeโ)
2I(v โง B) eโโโโ * (eโ โง Bโโeโโ) = eโโโโโ = -eโโโโโ = eโโโ = -Bโโeโ
eโโโโ * (eโ โง Bโโeโโ) = eโโโโโ = -Bโโeโ
eโโโโ * (eโ โง Bโโeโโ) = eโโโ = -Bโโeโ
=> 2 * p * (-Bโโeโ - Bโโeโ - Bโโeโ)
2(v ยท B) ยท B (-Bโโeโ -Bโโeโ -Bโโeโ) ยท (Bโโeโโ + Bโโeโโ + Bโโeโโ + Bโโeโโ + Bโโeโโ + Bโโeโโ)
--
= 0 + BโโBโโeโ - BโโBโโeโ - Bโโยฒeโ + 0 + 0
+ -BโโBโโeโ + 0 + BโโBโโeโ + 0 - Bโโยฒeโ + 0
+ BโโBโโeโ - BโโBโโeโ + 0 + 0 + 0 - Bโโยฒeโ
=> 2 * (BโโBโโeโ - BโโBโโeโ - Bโโยฒeโ - BโโBโโeโ + BโโBโโeโ - Bโโยฒeโ + BโโBโโeโ - BโโBโโeโ - Bโโยฒeโ)
v' = (sยฒ - pยฒ + Bโโยฒ + Bโโยฒ + Bโโยฒ + Bโโยฒ + Bโโยฒ + Bโโยฒ) eโ
+ 2 * s * (-Bโโeโ -Bโโeโ -Bโโeโ)
+ 2 * p * (-Bโโeโ - Bโโeโ - Bโโeโ)
+ 2 * (BโโBโโeโ - BโโBโโeโ - Bโโยฒeโ - BโโBโโeโ + BโโBโโeโ - Bโโยฒeโ + BโโBโโeโ - BโโBโโeโ - Bโโยฒeโ)
eโ Parts
(sยฒ - pยฒ + Bโโยฒ + Bโโยฒ + Bโโยฒ - Bโโยฒ - Bโโยฒ - Bโโยฒ) eโ
eโ Parts
2 * (s * -Bโโ + p * -Bโโ -BโโBโโ + BโโBโโ) eโ
eโ Parts
2 * (s * -Bโโ + p * -Bโโ + BโโBโโ - BโโBโโ) eโ
eโ Parts
2 * (s * -Bโโ + p * -Bโโ + BโโBโโ - BโโBโโ) eโ
v'โ = (sยฒ - pยฒ - Bโโยฒ + Bโโยฒ - Bโโยฒ + Bโโยฒ - Bโโยฒ + Bโโยฒ) * vโ
+ 2 * (s * -Bโโ + p * -Bโโ + BโโBโโ - BโโBโโ) * vโ
+ 2 * (s * Bโโ + p * Bโโ + BโโBโโ - BโโBโโ) * vโ
+ 2 * (s * -Bโโ + p * -Bโโ -BโโBโโ + BโโBโโ) * vโ
v'โ = 2 * (s * Bโโ + p * Bโโ + BโโBโโ - BโโBโโ) * vโ
+ (sยฒ - pยฒ - Bโโยฒ - Bโโยฒ + Bโโยฒ + Bโโยฒ + Bโโยฒ - Bโโยฒ) * vโ
+ 2 * (s * -Bโโ + p * -Bโโ + BโโBโโ - BโโBโโ) * vโ
+ 2 * (s * -Bโโ + p * -Bโโ + BโโBโโ - BโโBโโ) * vโ
v'โ = 2 * (s * -Bโโ + p * -Bโโ + BโโBโโ - BโโBโโ) * vโ
+ 2 * (s * Bโโ + p * Bโโ + BโโBโโ - BโโBโโ) * vโ
+ (sยฒ - pยฒ + Bโโยฒ - Bโโยฒ - Bโโยฒ - Bโโยฒ + Bโโยฒ + Bโโยฒ) * vโ
+ 2 * (s * -Bโโ + p * -Bโโ + BโโBโโ - BโโBโโ) * vโ
v'โ = 2 * (s * Bโโ + p * Bโโ + BโโBโโ - BโโBโโ) * vโ
+ 2 * (s * Bโโ + p * Bโโ - BโโBโโ + BโโBโโ) * vโ
+ 2 * (s * Bโโ + p * Bโโ - BโโBโโ + BโโBโโ) * vโ
+ (sยฒ - pยฒ + Bโโยฒ + Bโโยฒ + Bโโยฒ - Bโโยฒ - Bโโยฒ - Bโโยฒ) * vโ
static rotateVector4HB(r: Rot4, v: Vec4): Vec4 {
const s = r[0], xy = r[1], yz = r[2], zx = r[3],
zw = r[4], xw = r[5], yw = r[6], p = r[7];
// Helper squares
const s_2 = s * s;
const xy_2 = xy * xy, yz_2 = yz * yz, zx_2 = zx * zx;
const zw_2 = zw * zw, xw_2 = xw * xw, yw_2 = yw * yw;
const p_2 = p * p;
const out = new Float32Array(4);
// (sยฒ - Iยฒ)v + 2s(v ยท B) + 2I(v โง B) + 2(v ยท B)B - vBยฒ
// ((())) looks stupid but makes it WGSL-safe (no PEMDAS)
out[0] = ((s_2 - p_2 - xy_2 + yz_2 - zx_2 + zw_2 - xw_2 + yw_2) * v[0])
+ (2 * ((s * -xy) + (p * -zw) + (yz * zx) - (yw * xw)) * v[1])
+ (2 * ((s * zx) + (p * yw) + (yz * xy) - (zw * xw)) * v[2])
+ (2 * ((s * -xw) + (p * -yz) - (zw * zx) + (yw * xy)) * v[3]);
out[1] = (2 * ((s * xy) + (p * zw) + (zx * yz) - (xw * yw)) * v[0])
+ ((s_2 - p_2 - xy_2 - yz_2 + zx_2 + zw_2 + xw_2 - yw_2) * v[1])
+ (2 * ((s * -yz) + (p * -xw) + (zx * xy) - (zw * yw)) * v[2])
+ (2 * ((s * -yw) + (p * -zx) + (zw * yz) - (xw * xy)) * v[3]);
out[2] = (2 * ((s * -zx) + (p * -yw) + (xy * yz) - (xw * zw)) * v[0])
+ (2 * ((s * yz) + (p * xw) + (xy * zx) - (yw * zw)) * v[1])
+ ((s_2 - p_2 + xy_2 - yz_2 - zx_2 - zw_2 + xw_2 + yw_2) * v[2])
+ (2 * ((s * -zw) + (p * -xy) + (xw * zx) - (yw * yz)) * v[3]);
out[3] = (2 * ((s * xw) + (p * yz) + (xy * yw) - (zx * zw)) * v[0])
+ (2 * ((s * yw) + (p * zx) - (xy * xw) + (yz * zw)) * v[1])
+ (2 * ((s * zw) + (p * xy) - (yz * yw) + (zx * xw)) * v[2])
+ ((s_2 - p_2 + xy_2 + yz_2 + zx_2 - zw_2 - xw_2 - yw_2) * v[3]);
return out;
}
To export this as a matrix thats really easy, just remember you want COLUMN mayor.
So 0-3 are from vโ to vโ onto v'โ
static toMat4HB(r: Rot4): Mat4 {
const s = r[0], xy = r[1], yz = r[2], zx = r[3],
zw = r[4], xw = r[5], yw = r[6], p = r[7];
// Helper squares
const s_2 = s * s;
const xy_2 = xy * xy, yz_2 = yz * yz, zx_2 = zx * zx;
const zw_2 = zw * zw, xw_2 = xw * xw, yw_2 = yw * yw;
const p_2 = p * p;
const out = MAT4_IDENTITY.slice();
// all vโ parts IN TO OUT v'โ (0-3) to v'โ (12-15) - COLUMN MAYOR!!
// COLUMN 0 (Basis X: v=[1, 0, 0, 0])
out[0] = (s_2 - p_2 - xy_2 + yz_2 - zx_2 + zw_2 - xw_2 + yw_2);
out[1] = 2 * ((s * xy) + (p * zw) + (zx * yz) - (xw * yw));
out[2] = 2 * ((s * -zx) + (p * -yw) + (xy * yz) - (xw * zw));
out[3] = 2 * ((s * xw) + (p * yz) + (xy * yw) - (zx * zw));
// COLUMN 1 (Basis Y: v=[0, 1, 0, 0])
out[4] = 2 * ((s * -xy) + (p * -zw) + (yz * zx) - (yw * xw));
out[5] = (s_2 - p_2 - xy_2 - yz_2 + zx_2 + zw_2 + xw_2 - yw_2);
out[6] = 2 * ((s * yz) + (p * xw) + (xy * zx) - (yw * zw));
out[7] = 2 * ((s * yw) + (p * zx) - (xy * xw) + (yz * zw));
// COLUMN 2 (Basis Z: v=[0, 0, 1, 0])
out[8] = 2 * ((s * zx) + (p * yw) + (yz * xy) - (zw * xw));
out[9] = 2 * ((s * -yz) + (p * -xw) + (zx * xy) - (zw * yw));
out[10] = (s_2 - p_2 + xy_2 - yz_2 - zx_2 - zw_2 + xw_2 + yw_2);
out[11] = 2 * ((s * zw) + (p * xy) - (yz * yw) + (zx * xw));
// COLUMN 3 (Basis W: v=[0, 0, 0, 1])
out[12] = 2 * ((s * -xw) + (p * -yz) - (zw * zx) + (yw * xy));
out[13] = 2 * ((s * -yw) + (p * -zx) + (zw * yz) - (xw * xy));
out[14] = 2 * ((s * -zw) + (p * -xy) + (xw * zx) - (yw * yz));
out[15] = (s_2 - p_2 + xy_2 + yz_2 + zx_2 - zw_2 - xw_2 - yw_2);
return out;
}
R1 ร R2 - the SANE Heidelberg way (i think)
Im sure you can short this somehow but after all its expanding to 64 terms and will cancel 8 i think .. dono. ill just do it manually
R1*R2 = (R1[0] + R1[1] eโโ + R1[2] eโโ + R1[3] eโโ + R1[4] eโโ + R1[5] eโโ + R1[6] eโโ + R1[7] eโโโโ)
* (R2[0] + R2[1] eโโ + R2[2] eโโ + R2[3] eโโ + R2[4] eโโ + R2[5] eโโ + R2[6] eโโ + R2[7] eโโโโ)
= R1[0] R2[0] + R1[0] R2[1] eโโ + R1[0] R2[2] eโโ + R1[0] R2[3] eโโ + R1[0] R2[4] eโโ + R1[0] R2[5] eโโ + R1[0] R2[6] eโโ + R1[0] R2[7] eโโโโ
+ R1[1] eโโ R2[0] + R1[1] eโโ R2[1] eโโ + R1[1] eโโ R2[2] eโโ + R1[1] eโโ R2[3] eโโ + R1[1] eโโ R2[4] eโโ + R1[1] eโโ R2[5] eโโ + R1[1] eโโ R2[6] eโโ + R1[1] eโโ R2[7] eโโโโ
+ R1[2] eโโ R2[0] + R1[2] eโโ R2[1] eโโ + R1[2] eโโ R2[2] eโโ + R1[2] eโโ R2[3] eโโ + R1[2] eโโ R2[4] eโโ + R1[2] eโโ R2[5] eโโ + R1[2] eโโ R2[6] eโโ + R1[2] eโโ R2[7] eโโโโ
+ R1[3] eโโ R2[0] + R1[3] eโโ R2[1] eโโ + R1[3] eโโ R2[2] eโโ + R1[3] eโโ R2[3] eโโ + R1[3] eโโ R2[4] eโโ + R1[3] eโโ R2[5] eโโ + R1[3] eโโ R2[6] eโโ + R1[3] eโโ R2[7] eโโโโ
+ R1[4] eโโ R2[0] + R1[4] eโโ R2[1] eโโ + R1[4] eโโ R2[2] eโโ + R1[4] eโโ R2[3] eโโ + R1[4] eโโ R2[4] eโโ + R1[4] eโโ R2[5] eโโ + R1[4] eโโ R2[6] eโโ + R1[4] eโโ R2[7] eโโโโ
+ R1[5] eโโ R2[0] + R1[5] eโโ R2[1] eโโ + R1[5] eโโ R2[2] eโโ + R1[5] eโโ R2[3] eโโ + R1[5] eโโ R2[4] eโโ + R1[5] eโโ R2[5] eโโ + R1[5] eโโ R2[6] eโโ + R1[5] eโโ R2[7] eโโโโ
+ R1[6] eโโ R2[0] + R1[6] eโโ R2[1] eโโ + R1[6] eโโ R2[2] eโโ + R1[6] eโโ R2[3] eโโ + R1[6] eโโ R2[4] eโโ + R1[6] eโโ R2[5] eโโ + R1[6] eโโ R2[6] eโโ + R1[6] eโโ R2[7] eโโโโ
+ R1[7] eโโโโ R2[0] + R1[7] eโโโโ R2[1] eโโ + R1[7] eโโโโ R2[2] eโโ + R1[7] eโโโโ R2[3] eโโ + R1[7] eโโโโ R2[4] eโโ + R1[7] eโโโโ R2[5] eโโ + R1[7] eโโโโ R2[6] eโโ + R1[7] eโโโโ R2[7] eโโโโ
First lets solve all same planes to -1 / clean all eโโยฒ to -1
R1*R2 = (R1[0] + R1[1] eโโ + R1[2] eโโ + R1[3] eโโ + R1[4] eโโ + R1[5] eโโ + R1[6] eโโ + R1[7] eโโโโ)
* (R2[0] + R2[1] eโโ + R2[2] eโโ + R2[3] eโโ + R2[4] eโโ + R2[5] eโโ + R2[6] eโโ + R2[7] eโโโโ)
= R1[0] R2[0] + R1[0] R2[1] eโโ + R1[0] R2[2] eโโ + R1[0] R2[3] eโโ + R1[0] R2[4] eโโ + R1[0] R2[5] eโโ + R1[0] R2[6] eโโ + R1[0] R2[7] eโโโโ
+ R1[1] eโโ R2[0] - R1[1] R2[1] + R1[1] eโโ R2[2] eโโ + R1[1] eโโ R2[3] eโโ + R1[1] eโโ R2[4] eโโ + R1[1] eโโ R2[5] eโโ + R1[1] eโโ R2[6] eโโ + R1[1] eโโ R2[7] eโโโโ
+ R1[2] eโโ R2[0] + R1[2] eโโ R2[1] eโโ - R1[2] R2[2] + R1[2] eโโ R2[3] eโโ + R1[2] eโโ R2[4] eโโ + R1[2] eโโ R2[5] eโโ + R1[2] eโโ R2[6] eโโ + R1[2] eโโ R2[7] eโโโโ
+ R1[3] eโโ R2[0] + R1[3] eโโ R2[1] eโโ + R1[3] eโโ R2[2] eโโ - R1[3] R2[3] + R1[3] eโโ R2[4] eโโ + R1[3] eโโ R2[5] eโโ + R1[3] eโโ R2[6] eโโ + R1[3] eโโ R2[7] eโโโโ
+ R1[4] eโโ R2[0] + R1[4] eโโ R2[1] eโโ + R1[4] eโโ R2[2] eโโ + R1[4] eโโ R2[3] eโโ - R1[4] R2[4] + R1[4] eโโ R2[5] eโโ + R1[4] eโโ R2[6] eโโ + R1[4] eโโ R2[7] eโโโโ
+ R1[5] eโโ R2[0] + R1[5] eโโ R2[1] eโโ + R1[5] eโโ R2[2] eโโ + R1[5] eโโ R2[3] eโโ + R1[5] eโโ R2[4] eโโ - R1[5] R2[5] + R1[5] eโโ R2[6] eโโ + R1[5] eโโ R2[7] eโโโโ
+ R1[6] eโโ R2[0] + R1[6] eโโ R2[1] eโโ + R1[6] eโโ R2[2] eโโ + R1[6] eโโ R2[3] eโโ + R1[6] eโโ R2[4] eโโ + R1[6] eโโ R2[5] eโโ - R1[6] R2[6] + R1[6] eโโ R2[7] eโโโโ
+ R1[7] eโโโโ R2[0] + R1[7] eโโโโ R2[1] eโโ + R1[7] eโโโโ R2[2] eโโ + R1[7] eโโโโ R2[3] eโโ + R1[7] eโโโโ R2[4] eโโ + R1[7] eโโโโ R2[5] eโโ + R1[7] eโโโโ R2[6] eโโ + R1[7] R2[7]
eโโโโยฒ = eโโโโโโโโ = -eโโโโโโโโ = eโโโโโโโโ = -eโโโโโโ = eโโโโโโ = -eโโโโ = 1
Lets do all plane multipications sharing an axis
R1*R2 = (R1[0] + R1[1] eโโ + R1[2] eโโ + R1[3] eโโ + R1[4] eโโ + R1[5] eโโ + R1[6] eโโ + R1[7] eโโโโ)
* (R2[0] + R2[1] eโโ + R2[2] eโโ + R2[3] eโโ + R2[4] eโโ + R2[5] eโโ + R2[6] eโโ + R2[7] eโโโโ)
= R1[0] R2[0] + R1[0] R2[1] eโโ + R1[0] R2[2] eโโ + R1[0] R2[3] eโโ + R1[0] R2[4] eโโ + R1[0] R2[5] eโโ + R1[0] R2[6] eโโ + R1[0] R2[7] eโโโโ
// eโโโโโโ = -eโโ
+ R1[1] eโโ R2[0] - R1[1] R2[1] - R1[1] R2[2] eโโ + R1[1] R2[3] eโโ + R1[1] R2[4] eโโโโ - R1[1] R2[5] eโโ + R1[1] R2[6] eโโ - R1[1] R2[7] eโโ
// eโโโโ = -eโโโโ = eโโโโ eโโโโโโ = -eโโโโโโ = eโโโโ = -eโโ
+ R1[2] eโโ R2[0] + R1[2] R2[1] eโโ - R1[2] R2[2] - R1[2] R2[3] eโโ + R1[2] R2[4] eโโ + R1[2] R2[5] eโโโโ - R1[2] R2[6] eโโ - R1[2] R2[7] eโโ
// eโโโโ = -eโโโโ = eโโโโ eโโโโ = -eโโ
+ R1[3] eโโ R2[0] - R1[3] R2[1] eโโ + R1[3] R2[2] eโโ - R1[3] R2[3] - R1[3] R2[4] eโโ + R1[3] R2[5] eโโ + R1[3] R2[6] eโโโโ - R1[3] R2[7] eโโ
// eโโโโ = -eโโโโ = eโโโโ = -eโโโโ = eโโโโ eโโโโโโ = -eโโโโโโ = eโโโโโโ = -eโโโโโโ = eโโโโโโ = -eโโ
+ R1[4] eโโ R2[0] + R1[4] R2[1] eโโโโ - R1[4] R2[2] eโโ + R1[4] R2[3] eโโ - R1[4] R2[4] - R1[4] R2[5] eโโ + R1[4] R2[6] eโโ - R1[4] R2[7] eโโ
// eโโโโ = -eโโโโ = eโโโโ eโโโโโโ = -eโโโโ = eโโโโ = -eโโ
+ R1[5] eโโ R2[0] + R1[5] R2[1] eโโ + R1[5] R2[2] eโโโโ - R1[5] R2[3] eโโ + R1[5] R2[4] eโโ - R1[5] R2[5] - R1[5] R2[6] eโโ - R1[5] R2[7] eโโ
// eโโโโ = -eโโโโ = eโโโโ = -eโโโโ = eโโโโ eโโโโโโ = -eโโโโโโ = eโโโโโโ = -eโโโโ = eโโ = -eโโ
+ R1[6] eโโ R2[0] - R1[6] R2[1] eโโ + R1[6] R2[2] eโโ + R1[6] R2[3] eโโโโ - R1[6] R2[4] eโโ + R1[6] R2[5] eโโ - R1[6] R2[6] - R1[6] R2[7] eโโ
//
// eโโโโโโ = -eโโโโโโ = eโโโโโโ = -eโโโโโโ = eโโโโโโ = -eโโ
// eโโโโโโ = -eโโโโโโ = eโโโโโโ = -eโโ
// eโโโโโโ = -eโโโโ = eโโโโ = -eโโ
// eโโโโโโ = -eโโ eโโโโโโ = -eโโโโ = eโโโโ = -eโโ
// eโโโโโโ = -eโโโโ = eโโ = -eโโ
+ R1[7] eโโโโ R2[0] - R1[7] R2[1] eโโ - R1[7] R2[2] eโโ - R1[7] R2[3] eโโ - R1[7] R2[4] eโโ - R1[7] R2[5] eโโ - R1[7] R2[6] eโโ + R1[7] R2[7]
clean up and no notes (btw i made 4 mistakes here before having it checked for correctness)
R1*R2 = (R1[0] + R1[1] eโโ + R1[2] eโโ + R1[3] eโโ + R1[4] eโโ + R1[5] eโโ + R1[6] eโโ + R1[7] eโโโโ)
* (R2[0] + R2[1] eโโ + R2[2] eโโ + R2[3] eโโ + R2[4] eโโ + R2[5] eโโ + R2[6] eโโ + R2[7] eโโโโ)
= R1[0] R2[0] + R1[0] R2[1] eโโ + R1[0] R2[2] eโโ + R1[0] R2[3] eโโ + R1[0] R2[4] eโโ + R1[0] R2[5] eโโ + R1[0] R2[6] eโโ + R1[0] R2[7] eโโโโ
+ R1[1] R2[0] eโโ - R1[1] R2[1] - R1[1] R2[2] eโโ + R1[1] R2[3] eโโ + R1[1] R2[4] eโโโโ - R1[1] R2[5] eโโ + R1[1] R2[6] eโโ - R1[1] R2[7] eโโ
+ R1[2] R2[0] eโโ + R1[2] R2[1] eโโ - R1[2] R2[2] - R1[2] R2[3] eโโ + R1[2] R2[4] eโโ + R1[2] R2[5] eโโโโ - R1[2] R2[6] eโโ - R1[2] R2[7] eโโ
+ R1[3] R2[0] eโโ - R1[3] R2[1] eโโ + R1[3] R2[2] eโโ - R1[3] R2[3] - R1[3] R2[4] eโโ + R1[3] R2[5] eโโ + R1[3] R2[6] eโโโโ - R1[3] R2[7] eโโ
+ R1[4] R2[0] eโโ + R1[4] R2[1] eโโโโ - R1[4] R2[2] eโโ + R1[4] R2[3] eโโ - R1[4] R2[4] - R1[4] R2[5] eโโ + R1[4] R2[6] eโโ - R1[4] R2[7] eโโ
+ R1[5] R2[0] eโโ + R1[5] R2[1] eโโ + R1[5] R2[2] eโโโโ - R1[5] R2[3] eโโ + R1[5] R2[4] eโโ - R1[5] R2[5] - R1[5] R2[6] eโโ - R1[5] R2[7] eโโ
+ R1[6] R2[0] eโโ - R1[6] R2[1] eโโ + R1[6] R2[2] eโโ + R1[6] R2[3] eโโโโ - R1[6] R2[4] eโโ + R1[6] R2[5] eโโ - R1[6] R2[6] - R1[6] R2[7] eโโ
+ R1[7] R2[0] eโโโโ - R1[7] R2[1] eโโ - R1[7] R2[2] eโโ - R1[7] R2[3] eโโ - R1[7] R2[4] eโโ - R1[7] R2[5] eโโ - R1[7] R2[6] eโโ + R1[7] R2[7]
Collect
R'[0] s = R1[0] R2[0] - R1[1] R2[1] - R1[2] R2[2] - R1[3] R2[3] - R1[4] R2[4] - R1[5] R2[5] - R1[6] R2[6] + R1[7] R2[7]
R'[1] eโโ = R1[0] R2[1] + R1[1] R2[0] - R1[2] R2[3] + R1[3] R2[2] - R1[4] R2[7] - R1[5] R2[6] + R1[6] R2[5] - R1[7] R2[4]
R'[2] eโโ = R1[0] R2[2] + R1[1] R2[3] + R1[2] R2[0] - R1[3] R2[1] + R1[4] R2[6] - R1[5] R2[7] - R1[6] R2[4] - R1[7] R2[5]
R'[3] eโโ = R1[0] R2[3] - R1[1] R2[2] + R1[2] R2[1] + R1[3] R2[0] - R1[4] R2[5] + R1[5] R2[4] - R1[6] R2[7] - R1[7] R2[6]
R'[4] eโโ = R1[0] R2[4] - R1[1] R2[7] - R1[2] R2[6] + R1[3] R2[5] + R1[4] R2[0] - R1[5] R2[3] + R1[6] R2[2] - R1[7] R2[1]
R'[5] eโโ = R1[0] R2[5] + R1[1] R2[6] - R1[2] R2[7] - R1[3] R2[4] + R1[4] R2[3] + R1[5] R2[0] - R1[6] R2[1] - R1[7] R2[2]
R'[6] eโโ = R1[0] R2[6] - R1[1] R2[5] + R1[2] R2[4] - R1[3] R2[7] - R1[4] R2[2] + R1[5] R2[1] + R1[6] R2[0] - R1[7] R2[3]
R'[7] eโโโโ = R1[0] R2[7] + R1[1] R2[4] + R1[2] R2[5] + R1[3] R2[6] + R1[4] R2[1] + R1[5] R2[2] + R1[6] R2[3] + R1[7] R2[0]
static multiplyHB(a: Rot4, b: Rot4): Rot4 {
const s1 = a[0], xy1 = a[1], yz1 = a[2], zx1 = a[3], zw1 = a[4], xw1 = a[5], yw1 = a[6], p1 = a[7];
const s2 = b[0], xy2 = b[1], yz2 = b[2], zx2 = b[3], zw2 = b[4], xw2 = b[5], yw2 = b[6], p2 = b[7];
const s = (s1 * s2) - (xy1 * xy2) - (yz1 * yz2) - (zx1 * zx2) - (zw1 * zw2) - (xw1 * xw2) - (yw1 * yw2) + (p1 * p2);
const exy = (s1 * xy2) + (xy1 * s2) - (yz1 * zx2) + (zx1 * yz2) - (zw1 * p2) - (xw1 * yw2) + (yw1 * xw2) - (p1 * zw2);
const eyz = (s1 * yz2) + (xy1 * zx2) + (yz1 * s2) - (zx1 * xy2) + (zw1 * yw2) - (xw1 * p2) - (yw1 * zw2) - (p1 * xw2);
const ezx = (s1 * zx2) - (xy1 * yz2) + (yz1 * xy2) + (zx1 * s2) - (zw1 * xw2) + (xw1 * zw2) - (yw1 * p2) - (p1 * yw2);
const ezw = (s1 * zw2) - (xy1 * p2) - (yz1 * yw2) + (zx1 * xw2) + (zw1 * s2) - (xw1 * zx2) + (yw1 * yz2) - (p1 * xy2);
const exw = (s1 * xw2) + (xy1 * yw2) - (yz1 * p2) - (zx1 * zw2) + (zw1 * zx2) + (xw1 * s2) - (yw1 * xy2) - (p1 * yz2);
const eyw = (s1 * yw2) - (xy1 * xw2) + (yz1 * zw2) - (zx1 * p2) - (zw1 * yz2) + (xw1 * xy2) + (yw1 * s2) - (p1 * zx2);
const exyzw = (s1 * p2) + (xy1 * zw2) + (yz1 * xw2) + (zx1 * yw2) + (zw1 * xy2) + (xw1 * yz2) + (yw1 * zx2) + (p1 * s2);
const out = new Float32Array([s, exy, eyz, ezx, ezw, exw, eyw, exyzw]);
return out;
}