Disclaimer: this is not a textbook, this is just a short explanation, so you can use this library
Let's say we have a 2d-vector:
We can rewrite this expression in another form:
where
In geometric algebra we have three kinds of product of vectors: inner, outer, and geometric products.
You already know inner producs, it's just a dot product of vectors
So we are going to introduce the second kind of product - wedge product.
Wedge product (also called outer product) is defined as an oriented plane, that is common for those two vectors. Orientation is given by right-hand rule, and magnitude of that plane is equal to the area of parallelogram, defined by those two vectors. Actually wedge product and cross product are very much alike, except cross product is defined only for vectors in 3D, and outer product is defined in any dimensions.
![image](https://private-user-images.githubusercontent.com/26839955/293209239-30b2bab2-58f1-47ed-a62a-32ef717dbbf0.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MjIyNDE5MjAsIm5iZiI6MTcyMjI0MTYyMCwicGF0aCI6Ii8yNjgzOTk1NS8yOTMyMDkyMzktMzBiMmJhYjItNThmMS00N2VkLWE2MmEtMzJlZjcxN2RiYmYwLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDA3MjklMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwNzI5VDA4MjcwMFomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTAzN2MxZmY2MzBkZjc4NWFiNjEzY2RiNjQ0ZjhlNjMwOTkwZWUyYjkwNTk0MGU2MmY0MWI5NWM5NmMzZGE5YWImWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.cw9RvdJRGaN7fcWffsf8_JcKpeP9Z38lVC7C-T3I9-g)
Out of this definition we can conclude that
Outer product have not much use by itself, so I did not define outer product elements in the library by itself. But it participates in the geometric product, so let's look at it.
Now we can define final, and most useful kind of product - geometric product.
Let's look at the product of two basis vectors:
but
Let's see what we get if we square basis vectors:
Now we can write
For example, if we encounter such expression
But what if we square
It looks very much like imaginary unit
We remember that complex numbers are represented as two numbers:
There's not much to it in 2D, except the fact that vectors and complex numbers are elements of this unifying algebra,
operating on elements
Much more important is to get used to geometric product and its properties, so we can move on to more interesting algebras.
Similarly to 2D case, we have basis vectors
But when we multiply two vectors together, we get
We can see that
Just like in the 2D case, it's not much interesting by itself. Yes, we can get quaternion out of two vectors. This quaternion will rotate any vector by twice the angle between original two vectors. But that's it, if you're familiar with any math libraries out there, you will see all familiar functions.
In my library I define 2D vectors, and all familiar operators:
struct vector2 {
float32 x, y;
};
vector2 operator - (vector2);
vector2 operator + (vector2, vector2);
vector2 operator - (vector2, vector2);
vector2 operator * (float32, vector2);
vector2 operator * (vector2, float32);
vector2 operator / (vector2, float32);
float32 inner (vector2, vector2);
float32 norm_squared (vector2);
float32 norm (vector2);
void normalize (vector2 &);
vector2 normalized (vector2);
Note that functions like normalize
performs normalization in place, while normalized
returns vector of length 1.
struct complex {
float re, im;
};
complex operator - (complex);
complex operator + (complex, complex);
complex operator - (complex, complex);
complex operator * (float32, complex);
complex operator * (complex, float32);
complex operator * (complex, complex);
complex operator / (complex, float32);
complex operator / (float32, complex);
complex operator / (complex, complex);
void conjugate (complex &);
complex conjugated (complex);
float32 norm_squared (complex);
float32 norm (complex);
void normalize (complex &);
complex normalized (complex);
Geometric algebra allow us to define one more operator:
complex operator * (vector2 a, vector2 b) {
complex result;
result.re = a.x * b.x + a.y * b.y; // inner(a, b)
result.im = a.x * b.y - a.y * b.x; // outer(a, b)
return result;
}
In 3D I define vectors and quaternions with all familiar operations:
struct vector3 {
float x, y, z;
};
vector3 operator - (vector3);
vector3 operator + (vector3, vector3);
vector3 operator - (vector3, vector3);
vector3 operator * (float32, vector3);
vector3 operator * (vector3, float32);
vector3 operator / (vector3, float32);
float32 inner (vector3, vector3);
float32 norm_squared (vector3);
float32 norm (vector3);
void normalize (vector3 &);
vector3 normalized (vector3);
struct quaternion {
float i, j, k, w;
};
quaternion operator + (quaternion, quaternion);
quaternion operator - (quaternion, quaternion);
quaternion operator * (quaternion, float32);
quaternion operator * (float32, quaternion);
quaternion operator / (quaternion, float32);
quaternion operator * (quaternion, quaternion);
void conjugate (quaternion & q)
quaternion conjugated (quaternion q)
float32 norm_squared (quaternion q)
float32 norm (quaternion q)
void normalize (quaternion & q)
quaternion normalized (quaternion q)
quaternion inverse (quaternion q)
Geometric algebra allow us to define one more operator:
quaterion operator * (vector3 a, vector3 b) {
quaternion result;
result.i = a.y * b.z - a.z * b.y;
result.j = a.z * b.x - a.x * b.z;
result.k = a.x * b.y - a.y * b.x;
result.w = inner(a, b);
return result;
}