Stephane Breuils
Assistant professor
Steven De Keninck
Graphics engineer @ Angle Gaming Labs
we are always looking for talent !!
get in touch !
(navigate : first down, then right)
point
direction
line
plane
point
direction
line
plane
// construct lines
line_from_points (p1, p2)
line_from_points_and_dir (p, d)
line_from_plucker (a, b, c, d, e, f)
// construct planes
plane_from_points (p1, p2, p3)
plane_from_point_and_dirs (p, d1, d2)
plane_from_points_and_dir (p1, p2, d)
plane_from_point_and_line (p, l)
plane_from_equation (a, b, c, d)
// Intersections
intersect_line_plane (l, P)
intersect_plane_plane (P1, P2)
intersect_planes (P1, P2, P3)
// Projections
project_point_plane (p, P)
project_line_plane (l, P)
project_point_line (p, l)
point
direction
line
plane
// construct lines
line_from_points (p1, p2)
line_from_points_and_dir (p, d)
line_from_plucker (a, b, c, d, e, f)
// construct planes
plane_from_points (p1, p2, p3)
plane_from_point_and_dirs (p, d1, d2)
plane_from_points_and_dir (p1, p2, d)
plane_from_point_and_line (p, l)
plane_from_equation (a, b, c, d)
// Intersections
intersect_line_plane (l, P)
intersect_plane_plane (P1, P2)
intersect_planes (P1, P2, P3)
// Projections
project_point_plane (p, P)
project_line_plane (l, P)
project_point_line (p, l)
position
rotation
point
direction
line
plane
// construct lines
line_from_points (p1, p2)
line_from_points_and_dir (p, d)
line_from_plucker (a, b, c, d, e, f)
// construct planes
plane_from_points (p1, p2, p3)
plane_from_point_and_dirs (p, d1, d2)
plane_from_points_and_dir (p1, p2, d)
plane_from_point_and_line (p, l)
plane_from_equation (a, b, c, d)
// Intersections
intersect_line_plane (l, P)
intersect_plane_plane (P1, P2)
intersect_planes (P1, P2, P3)
// Projections
project_point_plane (p, P)
project_line_plane (l, P)
project_point_line (p, l)
position
rotation
matrix
// construct transformations
mtx_translate (x, y, z)
mtx_rotate_euler (h, p, b)
mtx_rotate_axis_angle (x, y, z, a)
mtx_look_at (from, too, pole)
// apply transformations
transform_point (M, p)
transform_direction (M, d)
transform_line (M, l)
transform_plane (M, P)
point
direction
line
plane
// construct lines
line_from_points (p1, p2)
line_from_points_and_dir (p, d)
line_from_plucker (a, b, c, d, e, f)
// construct planes
plane_from_points (p1, p2, p3)
plane_from_point_and_dirs (p, d1, d2)
plane_from_points_and_dir (p1, p2, d)
plane_from_point_and_line (p, l)
plane_from_equation (a, b, c, d)
// Intersections
intersect_line_plane (l, P)
intersect_plane_plane (P1, P2)
intersect_planes (P1, P2, P3)
// Projections
project_point_plane (p, P)
project_line_plane (l, P)
project_point_line (p, l)
position
rotation
matrix
quaternion
// construct transformations
mtx_translate (x, y, z)
mtx_rotate_euler (h, p, b)
mtx_rotate_axis_angle (x, y, z, a)
mtx_look_at (from, too, pole)
// apply transformations
transform_point (M, p)
transform_direction (M, d)
transform_line (M, l)
transform_plane (M, P)
// construct transformations
quat_from_euler (h, p, b)
quat_from_axis_angle (x, y, z, a)
quat_look_at (from, too, pole)
quat_from_matrix (M)
quat_to_matrix (Q)
// apply transformations
transform_point (Q, p)
transform_line (Q, l)
transform_plane (Q, P)
point
direction
line
plane
// construct lines
line_from_points (p1, p2)
line_from_points_and_dir (p, d)
line_from_plucker (a, b, c, d, e, f)
// construct planes
plane_from_points (p1, p2, p3)
plane_from_point_and_dirs (p, d1, d2)
plane_from_points_and_dir (p1, p2, d)
plane_from_point_and_line (p, l)
plane_from_equation (a, b, c, d)
// Intersections
intersect_line_plane (l, P)
intersect_plane_plane (P1, P2)
intersect_planes (P1, P2, P3)
// Projections
project_point_plane (p, P)
project_line_plane (l, P)
project_point_line (p, l)
position
rotation
matrix
quaternion
// construct transformations
mtx_translate (x, y, z)
mtx_rotate_euler (h, p, b)
mtx_rotate_axis_angle (x, y, z, a)
mtx_look_at (from, too, pole)
// apply transformations
transform_point (M, p)
transform_direction (M, d)
transform_line (M, l)
transform_plane (M, P)
// construct transformations
quat_from_euler (h, p, b)
quat_from_axis_angle (x, y, z, a)
quat_look_at (from, too, pole)
quat_from_matrix (M)
quat_to_matrix (Q)
// apply transformations
transform_point (Q, p)
transform_line (Q, l)
transform_plane (Q, P)
velocity
force
tensor
// LA LA Land
factor_QR (M)
factor_LDL (M)
factor_SVD (M)
factor_LU (M)
.. eigenvalues ..
.. gradient descent ..
.. LMA ..
.. back prop ..
.. AD ..
point
direction
line
plane
// construct lines
line_from_points (p1, p2)
line_from_points_and_dir (p, d)
line_from_plucker (a, b, c, d, e, f)
// construct planes
plane_from_points (p1, p2, p3)
plane_from_point_and_dirs (p, d1, d2)
plane_from_points_and_dir (p1, p2, d)
plane_from_point_and_line (p, l)
plane_from_equation (a, b, c, d)
// Intersections
intersect_line_plane (l, P)
intersect_plane_plane (P1, P2)
intersect_planes (P1, P2, P3)
// Projections
project_point_plane (p, P)
project_line_plane (l, P)
project_point_line (p, l)
position
rotation
matrix
quaternion
// construct transformations
mtx_translate (x, y, z)
mtx_rotate_euler (h, p, b)
mtx_rotate_axis_angle (x, y, z, a)
mtx_look_at (from, too, pole)
// apply transformations
transform_point (M, p)
transform_direction (M, d)
transform_line (M, l)
transform_plane (M, P)
// construct transformations
quat_from_euler (h, p, b)
quat_from_axis_angle (x, y, z, a)
quat_look_at (from, too, pole)
quat_from_matrix (M)
quat_to_matrix (Q)
// apply transformations
transform_point (Q, p)
transform_line (Q, l)
transform_plane (Q, P)
velocity
force
tensor
dual quaternion
// LA LA Land
factor_QR (M)
factor_LDL (M)
factor_SVD (M)
factor_LU (M)
.. eigenvalues ..
.. gradient descent ..
.. LMA ..
.. back prop ..
.. AD ..
// and even more code..
dquat_to_matrix (DQ)
dquat_from_matrix (M)
dquat_from_direction (d)
dquat_from_euler (h, p, b)
.. meshes ..
.. computational geometry ..
.. keeps going ..
point
direction
line
plane
// construct lines
line_from_points (p1, p2)
line_from_points_and_dir (p, d)
line_from_plucker (a, b, c, d, e, f)
// construct planes
plane_from_points (p1, p2, p3)
plane_from_point_and_dirs (p, d1, d2)
plane_from_points_and_dir (p1, p2, d)
plane_from_point_and_line (p, l)
plane_from_equation (a, b, c, d)
// Intersections
intersect_line_plane (l, P)
intersect_plane_plane (P1, P2)
intersect_planes (P1, P2, P3)
// Projections
project_point_plane (p, P)
project_line_plane (l, P)
project_point_line (p, l)
position
rotation
matrix
quaternion
// construct transformations
mtx_translate (x, y, z)
mtx_rotate_euler (h, p, b)
mtx_rotate_axis_angle (x, y, z, a)
mtx_look_at (from, too, pole)
// apply transformations
transform_point (M, p)
transform_direction (M, d)
transform_line (M, l)
transform_plane (M, P)
// construct transformations
quat_from_euler (h, p, b)
quat_from_axis_angle (x, y, z, a)
quat_look_at (from, too, pole)
quat_from_matrix (M)
quat_to_matrix (Q)
// apply transformations
transform_point (Q, p)
transform_line (Q, l)
transform_plane (Q, P)
velocity
force
tensor
dual quaternion
// LA LA Land
factor_QR (M)
factor_LDL (M)
factor_SVD (M)
factor_LU (M)
.. eigenvalues ..
.. gradient descent ..
.. LMA ..
.. back prop ..
.. AD ..
// and even more code..
dquat_to_matrix (DQ)
dquat_from_matrix (M)
dquat_from_direction (d)
dquat_from_euler (h, p, b)
.. meshes ..
.. computational geometry ..
.. keeps going ..
VECTOR AND MATRIX ALGEBRA
point
direction
line
plane
position
rotation
matrix
quaternion
velocity
force
dual quaternion
VECTOR AND MATRIX ALGEBRA
VECTOR
Geometric Objects are represented by choosing axes, taking measurements and writing down coefficients. Formulas produce and functions transform these measurements.
VECTOR AND MATRIX ALGEBRA
VECTOR AND MATRIX ALGEBRA
PROJECTIVE GEOMETRIC ALGEBRA
ANALYTIC GEOMETRY : VECTOR AND MATRIX ALGEBRA
ANALYTIC GEOMETRY : VECTOR AND MATRIX ALGEBRA
SYNTHETIC GEOMETRY : PROJECTIVE GEOMETRIC ALGEBRA
ANALYTIC GEOMETRY : VECTOR AND MATRIX ALGEBRA
SYNTHETIC GEOMETRY : PROJECTIVE GEOMETRIC ALGEBRA
ANALYTIC GEOMETRY : VECTOR AND MATRIX ALGEBRA
SYNTHETIC GEOMETRY : PROJECTIVE GEOMETRIC ALGEBRA
ANALYTIC GEOMETRY : VECTOR AND MATRIX ALGEBRA
SYNTHETIC GEOMETRY : PROJECTIVE GEOMETRIC ALGEBRA
{
{
2D
3D
.. just as in topology .. circle times circle ..
ANALYTIC GEOMETRY : VECTOR AND MATRIX ALGEBRA
SYNTHETIC GEOMETRY : PROJECTIVE GEOMETRIC ALGEBRA
{
{
2D
3D
{
4D
.. just as in topology .. circle times circle times circle ..
SYNTHETIC GEOMETRY : PROJECTIVE GEOMETRIC ALGEBRA
SYNTHETIC GEOMETRY : PROJECTIVE GEOMETRIC ALGEBRA
GEOMETRIC OBJECTS : POINTS, LINES, PLANES, ROTATIONS, TRANSLATIONS, ...
The elements of Geometry - in our case Projective Geometry
NOTE : we will work first in 2D, but in a way that will generalize to nD.
Represent Euclidean points/lines/... in n-d using an (n+1)d space.
We embed a 2D plane in a 3D space and call it the projective plane.
Represent Euclidean points/lines/... in n-d using an (n+1)d space.
We associate each projective point in 2D with a line through the origin in 3D
Represent Euclidean points/lines/... in n-d using an (n+1)d space.
Lines that do not intersect the projective plane are associated with infinite points
Represent Euclidean points/lines/... in n-d using an (n+1)d space.
#points_in_plane + #infinite_points = #lines_through_origin_in_3D
What about lines ?
Represent Euclidean points/lines/... in n-d using an (n+1)d space.
We associate each projective line in 2D with a plane through the origin in 3D
Represent Euclidean points/lines/... in n-d using an (n+1)d space.
The one plane parallel to the projective plane is associated with 1 infinite line
#points_in_plane + #infinite_points = #lines_through_origin_in_3D
#lines_in_plane + 1 = #planes_through_origin_in_3D
This works the same way in n-d and is called the Projective Map.
Represent Euclidean points/lines/... in n-d using an (n+1)d space.
The planes always intersect, and so do their corresponding lines .. even at infinity.
Represent Euclidean points/lines/... in n-d using an (n+1)d space.
The planes always intersect, and so do their corresponding lines .. even at infinity.
This means your code to intersect two lines has no exceptions, and the code that uses it has no if statements
...
// find intersection
var point = intersect_lines(line1, line2)
// always a valid result. (possibly infinite point).
// no checking - just use it !
...
What happens when you rotate around an infinite point ?
Represent Euclidean points/lines/... in n-d using an (n+1)d space.
#points_in_plane + #infinite_points = #lines_through_origin_in_3D
#lines_in_plane + 1 = #planes_through_origin_in_3D
#lines_through_origin_in_3D = #planes_through_origin_in_3D
each 3D line is orthogonal to exactly one 3D plane so we also have :
that also means the same amount of projective points and lines !
so we can relate projective lines and planes leading to Duality
Represent Euclidean points/lines/... in n-d using an (n+1)d space.
JOIN of two points is dual to MEET of their two dual lines
DUALITY : associate each projective point with one projective line
Represent Euclidean points/lines/... in n-d using an (n+1)d space.
JOIN of two points is dual to MEET of two lines
This means your code to intersect two lines can also be used to join two points.
function join_points(point1,point2) {
// dualize input points
var line1 = dual(point1);
var line2 = dual(point2);
// find intersection point.
var intersection_point = intersect_lines(line1, line2);
// return the dual line of this point
return dual(intersection_point);
}
point
lies on
line
intersect
Works for all your functions !!!!!
Represent Euclidean points/lines/... in n-d using an (n+1)d space.
Where are the formula's and numbers ? We have changed our difficult to write down arbitrary points and lines to slightly less difficult to write down entities through the origin. For lines through the origin we can use VECTORS, but lets think some more on the writing down .. enter Algebra.
What picture do you get when you see this equation ?
What picture do you get when you see this equation ?
ax² = bx | ax² = c |
bx = c | ax² + bx = c |
ax² + c = bx | bx + c = ax² |
Al-Khwarizmi's six problems
Today, one problem :
What was Al-Khwarizmi missing ?
ax² = bx | ax² = c |
bx = c | ax² + bx = c |
ax² + c = bx | bx + c = ax² |
Al-Khwarizmi's six problems
Today, one problem :
What was Al-Khwarizmi missing ?
no negative numbers, no zero
more numbers, less formulas, less code.
What was Al-Khwarizmi missing ?
zero negative numbers
maybe other numbers were hiding ?
What was Al-Khwarizmi missing ?
zero negative numbers
maybe other numbers were hiding ?
What was Al-Khwarizmi missing ?
zero negative numbers
maybe other numbers were hiding ?
What was Al-Khwarizmi missing ?
zero negative numbers
maybe other numbers were hiding ?
What was Al-Khwarizmi missing ?
zero negative numbers
maybe other numbers were hiding ?
What was Al-Khwarizmi missing ?
zero negative numbers
maybe other numbers were hiding ?
What was Al-Khwarizmi missing ?
zero negative numbers
maybe other numbers were hiding ?
What was Al-Khwarizmi missing ?
zero negative numbers
maybe other numbers were hiding ?
What was Al-Khwarizmi missing ?
zero negative numbers
maybe other numbers were hiding ?
THE GEOMETRIC NUMBERS
these are ofcourse the complex, hyperbolic and dual numbers. So why call them this ? lets find out ..
Addition and Scalar multiplication are trivial :
a lemon plus a lemon is almost always two lemons.
Addition and Scalar multiplication are trivial :
a lemon plus a lemon is almost always two lemons.
But what about multiplication ? - well lets find out ..
We add i to our bag of numbers. Each element in it is now of the form (a + bi), where a or b can be zero.
We add i to our bag of numbers. Each element in it is now of the form (a + bi), where a/b could be zero.
So, nothing special to remember ! No new multiplication, just a new element in the bag.
Easy to calculate - but what does it DO ?
Easy to calculate - but what do they DO ?
Elements that square to -1 related to ROTATIONS
\(\hookrightarrow\) this means \(-i\) is the inverse of \(i\)
Easy to calculate - but what do they DO ?
Elements that square to +1 related to REFLECTIONS
\(\hookrightarrow\) this means \(j\) is its own inverse !
Easy to calculate - but what do they DO ?
Elements that square to 0 related to TRANSLATIONS
\(\rightarrow (1+\epsilon)^{1.5}\) ?
ROTATIONS
REFLECTIONS
TRANSLATIONS
ROTATIONS
REFLECTIONS
TRANSLATIONS
Also, we want translations, rotations and reflections in one bag. But first - we solve the "smooth" and "weird 1+" problems.
With \(i^n\) where \(n \in \mathbb N\) we can rotate in steps. What about \(i^x\) with \(x \in \mathbb R\) ?
\(4^3 = 4*4*4\)
\(4^3 * 4^2 = (4 * 4 * 4) * (4 * 4) = 4^{3+2} = 4^5\)
\(\cfrac {4^3} {4^2} = \cfrac {4 * 4 * 4} {4 * 4} = 4^{3-2} = 4^1 = 4\)
\(\cfrac {4^2} {4^3} = \cfrac {4 * 4 } {4 * 4 * 4} = 4^{2-3} = 4^{-1} = \cfrac 1 4 \)
\(4^0 = 4^{1-1} = \cfrac 4 4 = 1\)
\({(4^2)}^2 = (4*4)^2 = (4*4)*(4*4) = 4^{2*2} = 4^4\)
\(4^x = {(2^2)}^x = 2^{2x}\)
\( a^n * a^m = a^{n+m} \)
\(\cfrac {a^n} {a^m} = a^{n-m} \)
\(a^1=a,\,a^0=1,\,a^{-1}=\cfrac 1 a\)
\({(a^n)}^m = a^{n*m}\)
\(a^x = {(b^{\alpha})}^x = b^{\alpha x}\)
\(\hookrightarrow\)
All exponential functions are the same, with x scaled by some constant \(\alpha\).
So if we can calculate one smooth \(a^x\) with \(x \in \mathbb R\), we're done.
With \(i^n\) where \(n \in \mathbb N\) we can rotate in steps. What about \(i^x\) with \(x \in \mathbb R\) ?
\({(4^2)}^2 = (4*4)^2 = (4*4)*(4*4) = 4^{2*2} = 4^4\)
\(4^x = {(2^2)}^x = 2^{2x}\)
\(a^x = {(b^{\alpha})}^x = b^{\alpha x}\)
\(\hookrightarrow\)
All exponential functions are the same, with x scaled by some constant \(\alpha\).
So if we can calculate one smooth \(a^x\) with \(x \in \mathbb R\), we're done.
Thanks to Euler, we know an easy way to calculate one of these functions, he discovered the following series :
\(e^x = 1 + \frac x 1 + \frac {x^2} {2*1} + \frac {x^3} {3*2*1} + ...\)
power can be ANYTHING
powers \(\in \mathbb N\)
With \(i^n\) where \(n \in \mathbb N\) we can rotate in steps. What about \(i^x\) with \(x \in \mathbb R\) ?
\({(4^2)}^2 = (4*4)^2 = (4*4)*(4*4) = 4^{2*2} = 4^4\)
\(4^x = {(2^2)}^x = 2^{2x}\)
\(a^x = {(b^{\alpha})}^x = b^{\alpha x}\)
\(\hookrightarrow\)
All exponential functions are the same, with x scaled by some constant \(\alpha\).
So if we can calculate one smooth \(a^x\) with \(x \in \mathbb R\), we're done.
\(e^x = 1 + \frac x 1 + \frac {x^2} {2*1} + \frac {x^3} {3*2*1} + ...\)
power can be ANYTHING
powers \(\in \mathbb N\)
So, if you see \(e^x\), the \(e\) ONLY tells you its an exponential function, the \(x\) has all the information. With our new numbers, \(e^{\alpha i}\) are thus rotations and \(e^{\alpha \epsilon}\) are translations.
With \(i^n\) where \(n \in \mathbb N\) we can rotate in steps. What about \(i^x\) with \(x \in \mathbb R\) ?
\(e^{\alpha i}=\sum \limits_{n=0}^\infty \cfrac {(\alpha i)^n} {n!} = \cos \alpha + i \sin \alpha\)
\(\rightarrow\) Exponentiate \(\alpha i\) to get a rotation (these are our smooth rotations)
\(e^{\alpha \epsilon}=\sum \limits_{n=0}^\infty \cfrac {(\alpha \epsilon)^n} {n!} = 1 + \alpha \epsilon\)
\(\rightarrow\) Exponentiate \(\alpha \epsilon\) to get a translation. (this is that weird \(+1\))
\(e^x\) when \(x \notin \mathbb R\) are called the roots of unity. (multiplying with them wont change scale, i.e. : \({(e^x)}^n=1\)
Recap :
We define one last property, when we add more than one of these,
lets call them \(\mathbf e_1\) and \(\mathbf e_2\), we demand that they anticommute :
\(\mathbf e_1 \mathbf e_2 = - \mathbf e_2 \mathbf e_1\)
Let's now use these numbers to properly write down vectors ..
So far, we've always added just one element to our bag of numbers \(\mathbb R\)
We'll want more elements in the same bag, and names will get confusing, so let's first introduce some notation :
\(\mathbb R_{positive,negative,zero}\)
\(\mathbb R_{0,1,0}\,\rightarrow\) one extra element that squares to \(-1\)
\(\mathbb R_{0,0,1}\,\rightarrow\) one extra element that squares to \(0\)
\(\mathbb R_{9,6,0}\,\rightarrow\) nine extra element that square to \(1\)
and six extra elements that square to \(-1\)
These elements are called generators, and are typically written \(\mathbf e_0, \mathbf e_1, \mathbf e_2, ...\)
Let's try with two generators - we take \(\mathbb R\) and add two positive generators \(\mathbf e_1, \mathbf e_2\) to represent our X and Y axis
\(\mathbb R_{2,0,0}\) : \(\quad\mathbb R \,{\scriptstyle\oplus}\, \mathbf e_1 \,{\scriptstyle\oplus}\, \mathbf e_2,\quad\mathbf e_1^2=+1,\,\mathbf e_2^2=+1\)
\(\vec a\vec b = (a_1{\color{green}\mathbf e_1} + a_2{\color{blue}\mathbf e_2}) (b_1{\color{green}\mathbf e_1} + {b_2\color{blue}\mathbf e_2}) \)
\(= a_1b_1{\color{green}\mathbf e_1^2} + a_2b_2{\color{blue}\mathbf e_2^2}\)
\(+ a_1b_2{\color{green}\mathbf e_1}{\color{blue}\mathbf e_2} + a_2b_1{\color{blue}\mathbf e_2}{\color{green}\mathbf e_1}\)
\(\rightarrow\) these are scalar \(\in \mathbb R\)
\(\rightarrow\) new type ! no scalar, no vector !
Grassmann : different vectors ANTICOMMUTE : \(e_1e_2 = -e_2e_1\)
Any vector is a linear combination of \(\mathbf e_1, \mathbf e_2\), the product of two vectors is :
\(\rightarrow\) these are vectors
Let's try with two generators - we take \(\mathbb R\) and add two positive generators \(\mathbf e_1, \mathbf e_2\) to represent our X and Y basis vectors
\(\mathbb R_{2,0,0}\) : \(\quad\mathbb R \,{\scriptstyle\oplus}\, {\color{green}\mathbf e_1} \,{\scriptstyle\oplus}\, {\color{blue}\mathbf e_2},\quad{\color{green}\mathbf e_1}^2=+1,\,{\color{blue}\mathbf e_2}^2=+1\)
\(\vec a\vec b = (a_1{\color{green}\mathbf e_1} + a_2{\color{blue}\mathbf e_2}) (b_1{\color{green}\mathbf e_1} + {b_2\color{blue}\mathbf e_2}) \)
\(= a_1b_1 + a_2b_2\)
\(+ (a_1b_2-a_2b_1){\color{green}\mathbf e_1}{\color{blue}\mathbf e_2}\)
\(\rightarrow\) these are scalar \(\in \mathbb R\)
\(\rightarrow\) new type ! no scalar, no vector !
bivector
Grassmann : different vectors ANTICOMMUTE : \(e_1e_2 = -e_2e_1 = e_{12} = -e_{21}\)
Any vector is a linear combination of \(\mathbf e_1, \mathbf e_2\), the product of two vectors is :
\(\rightarrow\) these are vectors
Let's try with two generators - we take \(\mathbb R\) and add two positive generators \(\mathbf e_1, \mathbf e_2\) to represent our X and Y basis vectors
\(\mathbb R_{2,0,0}\) : \(\quad\mathbb R \,{\scriptstyle\oplus}\, {\color{green}\mathbf e_1} \,{\scriptstyle\oplus}\, {\color{blue}\mathbf e_2},\quad{\color{green}\mathbf e_1}^2=+1,\,{\color{blue}\mathbf e_2}^2=+1\)
\(\vec a\vec b = (a_1{\color{green}\mathbf e_1} + a_2{\color{blue}\mathbf e_2}) (b_1{\color{green}\mathbf e_1} + {b_2\color{blue}\mathbf e_2}) \)
\(= a_1b_1 + a_2b_2\)
\(+ (a_1b_2-b_1a_2){\color{red}\mathbf e_{12}}\)
\(\rightarrow\) these are scalar \(\in \mathbb R\)
\(\rightarrow\) new type ! no scalar, no vector !
bivector
Grassmann : different vectors ANTICOMMUTE : \(e_1e_2 = -e_2e_1 = e_{12} = -e_{21}\)
Any vector is a linear combination of \(\mathbf e_1, \mathbf e_2\), the product of two vectors is :
\(\rightarrow\) these are vectors
So, we add two elements \(\mathbf e_1, \mathbf e_2\), and through multiplication we get another new element, \(\mathbf e_{12}\). It is the plane our two vectors lie in.
\(\mathbb R_{2,0,0} :\)
\(\mathbb R\)
\(\mathbf e_1,\mathbf e_2\)
\(\mathbf e_{12}\)
\(\rightarrow\) 0-dimensional "scalar"
\(\rightarrow\) 1-dimensional "vector"
\(\rightarrow\) 2-dimensional "bivector"
a vector is a 1D oriented quantity. (line)
a bivector is a 2D oriented quantity. (plane)
a trivector is a 3D oriented quantity (volume)
so, only two calculation rules ! \(e_xe_x = \{+1,-1,0\},\quad e_xe_y = -e_xe_y\)
Let's try a few examples, we are still in \(\mathbb R_{2,0,0}\). So \(\mathbf e_1,\mathbf e_2\), both square to +1
\(3\mathbf e_1 2\mathbf e_1 = \)
\(3\mathbf e_1 2\mathbf e_2 = \)
\((3\mathbf e_1 + \mathbf e_2) \mathbf e_2 =\)
\(\mathbf e_2 \mathbf e_{12} = \)
\(\mathbf e_{12} \mathbf e_{12} = \)
so, only two calculation rules ! \(e_xe_x = \{+1,-1,0\},\quad e_xe_y = -e_xe_y\)
Let's try a few examples, we are still in \(\mathbb R_{2,0,0}\). So \(\mathbf e_1,\mathbf e_2\), both square to +1
\(3\mathbf e_1 2\mathbf e_1 = 6\)
\(3\mathbf e_1 2\mathbf e_2 = \)
\((3\mathbf e_1 + \mathbf e_2) \mathbf e_2 =\)
\(\mathbf e_2 \mathbf e_{12} = \)
\(\mathbf e_{12} \mathbf e_{12} = \)
so, only two calculation rules ! \(e_xe_x = \{+1,-1,0\},\quad e_xe_y = -e_xe_y\)
Let's try a few examples, we are still in \(\mathbb R_{2,0,0}\). So \(\mathbf e_1,\mathbf e_2\), both square to +1
\(3\mathbf e_1 2\mathbf e_1 = 6\)
\(3\mathbf e_1 2\mathbf e_2 = 6 \mathbf e_1\mathbf e_2 = 6 \mathbf e_{12}\)
\((3\mathbf e_1 + \mathbf e_2) \mathbf e_2 =\)
\(\mathbf e_2 \mathbf e_{12} = \)
\(\mathbf e_{12} \mathbf e_{12} = \)
so, only two calculation rules ! \(e_xe_x = \{+1,-1,0\},\quad e_xe_y = -e_xe_y\)
Let's try a few examples, we are still in \(\mathbb R_{2,0,0}\). So \(\mathbf e_1,\mathbf e_2\), both square to +1
\(3\mathbf e_1 2\mathbf e_1 = 6\)
\(3\mathbf e_1 2\mathbf e_2 = 6 \mathbf e_1\mathbf e_2 = 6 \mathbf e_{12}\)
\((3\mathbf e_1 + \mathbf e_2) \mathbf e_2 = 3\mathbf e_{12} + 1\)
\(\mathbf e_2 \mathbf e_{12} =\)
\(\mathbf e_{12} \mathbf e_{12} = \)
\(3\mathbf e_1 2\mathbf e_1 = 6\)
so, only two calculation rules ! \(e_xe_x = \{+1,-1,0\},\quad e_xe_y = -e_xe_y\)
Let's try a few examples, we are still in \(\mathbb R_{2,0,0}\). So \(\mathbf e_1,\mathbf e_2\), both square to +1
\(3\mathbf e_1 2\mathbf e_1 = 6\)
\(3\mathbf e_1 2\mathbf e_2 = 6 \mathbf e_1\mathbf e_2 = 6 \mathbf e_{12}\)
\((3\mathbf e_1 + \mathbf e_2) \mathbf e_2 = 3\mathbf e_{12} + 1\)
\(\mathbf e_2 \mathbf e_{12} = \mathbf e_2 \mathbf e_1 \mathbf e_2 = - \mathbf e_1 \mathbf e_2 \mathbf e_2 = - \mathbf e_1\)
\(\mathbf e_{12} \mathbf e_{12} = \)
so, only two calculation rules ! \(e_xe_x = \{+1,-1,0\},\quad e_xe_y = -e_xe_y\)
Let's try a few examples, we are still in \(\mathbb R_{2,0,0}\). So \(\mathbf e_1,\mathbf e_2\), both square to +1
\(3\mathbf e_1 2\mathbf e_1 = 6\)
\(3\mathbf e_1 2\mathbf e_2 = 6 \mathbf e_1\mathbf e_2 = 6 \mathbf e_{12}\)
\((3\mathbf e_1 + \mathbf e_2) \mathbf e_2 = 3\mathbf e_{12} + 1\)
\(\mathbf e_2 \mathbf e_{12} = \mathbf e_2 \mathbf e_1 \mathbf e_2 = - \mathbf e_1 \mathbf e_2 \mathbf e_2 = - \mathbf e_1\)
\(\mathbf e_{12} \mathbf e_{12} = \mathbf e_1 \mathbf e_2 \mathbf e_1 \mathbf e_2 = - \mathbf e_1 \mathbf e_1 \mathbf e_2 \mathbf e_2 = -1 \)
so, only two calculation rules ! \(e_xe_x
\{+1,-1,0\},\quad e_xe_y = -e_xe_y\)
square any generator, replace with metric
swap two generators, change sign
product of any two vectors in \(\mathbb R_{3,0,0}\) :
\((a\mathbf e_1 + b\mathbf e_2 + c\mathbf e_3)(d\mathbf e_1 + e\mathbf e_2 + f\mathbf e_3) = ...\)
\(=ad + be + cf + (ae-bd)\mathbf e_{12} + (af-cd)\mathbf e_{13} + (bf-ce)\mathbf e_{23}\)
The product of two VECTORS is a SCALAR + BIVECTOR
\(a*b\) \(=\) \(a \cdot b\) \(+\) \(a \wedge b\)
geometric product
inner product (dot)
outer product (wedge, 'cross')
\(a*b\) \(=\) \(a \cdot b\) \(+\) \(a \times b\)
\(\mathbb R_{3,0,0}\)
Scalars + Bivectors = QUATERNIONS
RECAP :
\(ab\) = geometric product
\(a \cdot b\) = inner product
\(a \wedge b\) = outer product
\(a^*\) = dual of \(a\)
\(a \vee b\) = \((a^* \wedge b^*)^*\)
\(\mathbb R_{2,0,1}\)
Scalars + Bivectors = Translate + Rotate
We are now ready to create the bag we need for 2D PGA - The projective plane !!!!
1 | e0 | e1 | e2 | e01 | e02 | e12 | e123 |
---|
vector
bivector
scalar
trivec
projective LINES
projective POINTS
+1 | 0 | +1 | +1 | 0 | 0 | -1 | 0 |
---|
We are now ready to create the bag we need for 2D PGA - The projective plane
1 | e0 | e1 | e2 | e01 | e02 | e12 | e123 |
---|
vector
bivector
scalar
trivec
projective LINES
projective POINTS
Point at (x,y) :
Line between points \(p_1, p_2\) :
Line with equation \(a\mathbf x + b\mathbf y = c\) :
Intersect lines \(\ell_1, \ell_2\) :
Rotation of \(\alpha\) around point \(p\) :
Translate \(\alpha\) with infinite point \(p\) :
Angle between lines \(L_1, L_2\) :
Project point on line :
\(x\mathbf e_{02} + y\mathbf e_{01} + \mathbf e_{12}\)
\(p_1 \vee p_2\)
\(a\mathbf e_1 + b\mathbf e_2 - c\mathbf e_0\)
\(L_1 \wedge L_2\)
\(e^{\alpha p}\)
\(e^{\alpha p}\)
\(\cos^{-1}(L_1 \cdot L_2)\)
\( (L \cdot p) L\)
+1 | 0 | +1 | +1 | 0 | 0 | -1 | 0 |
---|
It is all exactly the same in 3D, just some more elements :
1 | e0 | e1 | e2 | e3 | e01 | e02 | e03 |
---|
Point at (x,y,z) :
Line between points \(p_1, p_2\) :
Plane with equation \(a\mathbf x + b\mathbf y + c\mathbf z = d\) :
Intersect planes \(P_1, P_2\) :
Rotation of \(\alpha\) around line \(L\) :
Translate \(\alpha\) with infinite line \(L\) :
Angle between planes \(P_1, P_2\) :
Project point on plane :
\(x\mathbf e_{023} + y\mathbf e_{013} + z\mathbf e_{012} + \mathbf e_{123}\)
\(p_1 \vee p_2\)
\(a\mathbf e_1 + b\mathbf e_2 + c\mathbf e_3 - d\mathbf e_0\)
\(P_1 \wedge P_2\)
\(e^{\alpha L}\)
\(e^{\alpha L}\)
\(\cos^{-1}(P_1 \cdot P_2)\)
\( (L \cdot p) L\)
+1 | 0 | +1 | +1 | +1 | 0 | 0 | 0 |
---|
e12 | e13 | e23 | e012 | e013 | e023 | e123 | e0123 |
---|
scalar | vector | bivector | trivector | 4-vec |
---|
PROJECTIVE PLANES | PROJECTIVE LINES | PROJECTIVE POINTS |
---|
-1 | -1 | -1 | 0 | 0 | 0 | -1 | 0 |
---|
point
direction
line
plane
// construct lines
line_from_points (p1, p2) = p1&p2
line_from_points_and_dir (p, d) = p&(p+d)
// construct planes
plane_from_points (p1,p2,p3) = p1&p2&p3
plane_from_point_and_dirs (p,d1,d2) = p&(p+d1)&(p+d2)
plane_from_points_and_dir (p1,p2,d) = p1&p2&(p1+d)
plane_from_point_and_line (p,l) = p&l
plane_from_equation (a,b,c,d) = ae1+be2+ce3-de0
// Intersections
intersect_line_plane (l, P) = l^P
intersect_plane_plane (P1, P2) = P1^P2
intersect_planes (P1, P2, P3) = P1^P2^P3
// Projections
project_point_plane (p, P) = P|p*P
project_line_plane (l, P) = P|l*P
project_point_line (p, l) = l|p*l
position
rotation
matrix
quaternion
// construct transformations -> motors, not matrices !
translate (x,y,z) = E**(x*e01+y*e02+z*e03)
rotate_euler (h,p,b) = E**(b*e12)*E**(p*e23)*E**(h*e13)
rotate_axis_angle (x,y,z,a) = E**(a*x*e23+a*y*e13+a*z*e12)
look_at (from,too,pole) = (1 + (e1-from)*(to-from))
// apply transformations -> note : all the same..
transform_point (M, p) = M*p*~M
transform_direction (M, d) = M*d*~M
transform_line (M, l) = M*l*~M
transform_plane (M, P) = M*P*~M
// construct transformations
quat_from_euler (h, p, b)
quat_from_axis_angle (x, y, z, a)
quat_look_at (from, too, pole)
quat_from_matrix (M)
quat_to_matrix (Q)
// apply transformations
transform_point (Q, p)
transform_line (Q, l)
transform_plane (Q, P)
Same as opening but now in PGA - implementation is shorter than function names !
no coordinates - no chirality - no gimbal lock - no conversions
Where to go from here ?
Remember that PGA is very, very, very young. Not a lot of material is available, and even less implementations and examples. Keep an eye out for the Siggraph courses on PGA, and in the mean time, here are some papers and links :
Dr Gunn's page on PGA :
My ganja.js GA implementation :
My collection of examples :
questions ? need help ? \(\rightarrow\) steven at enki dot ws
By Stephane Breuils
An intuitive and hands-on introduction to Projective Geometric Algebra for Programmers and Artists.