Experimental type-safe geometric algebra for Rust

Related tags

Game development pga
Overview

Projective Geometric Algebra

This library is a Rust code generator, generating the mathematics you need for a geometric algebra library.

I made it mostly to teach myself the fundamentals of PGA.

Consider it an experiment.

Inspiration

The Geometric Algebra course at Siggraph 2019 https://bivector.net/index.html

Foundation of Game Engine Development, Volume 1, by Eric Lengyel http://terathon.com/blog/projective-geometric-algebra-done-right/ http://terathon.com/pga_lengyel.pdf

3D example

Vector names: X Y Z W

Grammar: X²=1 Y²=1 Z²=1 W²=0

Types:

  • Vec3: X Y Z (direction)
  • Vec4: X Y Z W (homogenous point)
  • Point3: X Y Z W=1 (normalized point)
  • Line3: WX WY WZ YZ ZX XY (direction + moment of a Plücker line)
  • Plane YZW ZXW XYW ZYX (normal + offset)
  • Translator3 YZ ZX XY XYZW (translation primitive)
  • Rotor3 WX WY WZ XYZW (rotation primitive, a.k.a. quaternion)
  • Motor3 WX WY WZ XYZW YZW ZXW XYW S (translator + rotor, a.k.a. dual quaternion)

From the above definition, this library generates all the operations that can be done on these types. For instance, it will autmatically realize that Point3 ^ Point3 -> Line3 (wedging two points gives the line that goes through those points) and Plane V Line3 -> Vec4 (the antiwedge of a plane and a line is the point where the plane and line interesect).

The generated code uses newtypes for all vectors and blades, so that x = y; wouldn't compile (since x and y coordinates run along different vectors).

Details

Algebra

You first specify the the algebra by the signs of the product of the base vectors, e.g. 0++ for 2d projective geometric algebra, which would be the base vectors e0²=0, e1²=1, e2²=1.

You can also give your base vectors more descriptive names, e.g. X/Y/Z/W for your standard homogeneous 3D PGA.

From these all products are generated, creating bivectors (XY, YZ etc), trivectors (XYZ etc), and so on. Together with the Real type they make up the blades of the system. All values are a linear combination of the blades, e.g. 0.5 + 2*X - 42*XZ.

Named blade groups (types)

We can give names to groups of blades, for instance naming Vec3={X,Y,Z}, Point3={X,Y,Z,W}, Line3={WX, WY, WZ, YZ, ZX, XY} (Plücker coordinates), Plane={YZW,ZXW,XYW,ZYX} etc.

Note that a value can have multiple types. For instance, in the example above, any Vec3 or also a Point3 with W=0 (an infinite point). The types thus form a Venn diagram.

These types will be combined against each other for all operations, unary (like the dual) as well as binary (multiplication, dot product, wedge, regressive, ...). The generator will notice what dimensions (blades) will be the output, and deduce a type name form that. For instance, Point3 ^ Point3 -> Line3 (wedging two points gives you the line that goes through both points) or Plane V Line3 -> Point3 (the antiwedge of a plane and a line is the point where the plane and line interesect).

A very brief introduction to Geometric Algebra

As a programmer, my view of Geometric Algebra is as a type safe superset of linear algebra that unifies many differents parts of the standard 3D programming toolset into one theory. Using GA we can combine vectors, points, plücker lines, planes, translators, rotors (quaternions) and motors (dual quaternions) into one framework. This library generates the code for these primitves and all valid operations you can do using them.

Notation

Geometric Algebra (GA) is great and very general. We will focus first on the interesting subset of 3D Projective Geometric Algebra (PGA). This is where you denote point and vectors with an extra projective dimension w and define w=0 as directions and w=1 as cartesian coordinates. Thus a vector is expressed as [x, y, z, w].

In textbook geometric algebra, the base vectors are given the names e1/e2/e3/e4 (or sometimes e0/e1/e2/e3). Due to this unfamiliarity and inconsistency I prefer to simply rename them to the familiar names X/Y/Z/W.

So, I use this notations:

2D PGA:

| Class     | Blades    | Description |
| --------- | --------- | ----------- |
| Scalar    | S         | The set of real numbers
| Vectors   | X  Y  W   | Orthogonal dimensions in projective space
| Bivectors | YW WX XY  | Orthogonal planes with normals `X Y W`
| Trivector | XYW       | Represents a volume

I will use lower case letters for x,y,z,w for values (e.g. 3.14) and upper case letters X,Y,Z,W for the basis vectors, which can be thought of as the type of the value.

Vectors and planes

Consider two arrows on the ground, both with heir names engraved on them: e and n, and they happen to be pointing east and north. What can you do with two arrows?

   e          ^
------>       |
             n|
              |

One thing you can do with them, is to stick them together at their bases. We call this wedging:

 ^
 |
n|
 +------>
     e

In geometric algebra, we write this as n^e. If one arrow has length 2 and the other length 3 we get 2N^3E = 6N^E = 6NE`. This represents the plane spanned by the two vectors, with the magnitude representing the area of the parallelogram spanned by the vectors.

Thinking in geometric algebra.

The value x means "How much along the X axis?".

XY: How much area do I have in the plane spanned by XY plane, i.e. the plane pointing along the positive Z axis.

Say you have three orthogonal vectors which are the sides of a cube. What is the volume of them together?

Classical thinking would get you |v0|*|v1|*|v2|. In GA, you instead think of the dimensions involved.

Each vector has three scalars: {x: X, y: Y, z: Z} (w=0 since these are directions). We want to get to the volume, which has dimension XYZ. We want to from low dimension (directions) to a higher one (volume), so what do we do? We wedge them together! Wedging is joining many lower-dimensions things (lines) into one higher dimension things (volume). So the answer is v0^v1^v2. And then you are done!

You might also like...
Simple retro game made using Rust bracket-lib by following "Herbert Wolverson's Hands on Rust" book.

Flappy Dragon Code from This program is a result of a tutorial i followed from Herbert Wolverson's Hands-on Rust Effective Learning through 2D Game De

A rust chess implementation using a neural network scoring function built on huggingface/candle + rust + wasm

Rusty Chess What is it? Rusty Chess aims to be a high quality embeddable chess engine that runs entirely locally in the browser (no backend required).

A Rust wrapper and bindings of Allegro 5 game programming library

RustAllegro A thin Rust wrapper of Allegro 5. Game loop example extern crate allegro; extern crate allegro_font; use allegro::*; use allegro_font::*;

High performance Rust ECS library
High performance Rust ECS library

Legion aims to be a feature rich high performance Entity component system (ECS) library for Rust game projects with minimal boilerplate. Getting Start

A refreshingly simple data-driven game engine built in Rust

What is Bevy? Bevy is a refreshingly simple data-driven game engine built in Rust. It is free and open-source forever! WARNING Bevy is still in the ve

Rust library to create a Good Game Easily

ggez What is this? ggez is a Rust library to create a Good Game Easily. The current version is 0.6.0-rc0. This is a RELEASE CANDIDATE version, which m

RTS game/engine in Rust and WebGPU
RTS game/engine in Rust and WebGPU

What is this? A real time strategy game/engine written with Rust and WebGPU. Eventually it will be able to run in a web browser thanks to WebGPU. This

unrust - A pure rust based (webgl 2.0 / native) game engine

unrust A pure rust based (webgl 2.0 / native) game engine Current Version : 0.1.1 This project is under heavily development, all api are very unstable

Rust bindings for GDNative

GDNative bindings for Rust Rust bindings to the Godot game engine. Website | User Guide | API Documentation Stability The bindings cover most of the e

Owner
Emil Ernerfeldt
Rust coder at Embark Studios. Previously worked with physics simulation, games, 3D scanning and cyber security. I am @ernerfeldt on Twitter
Emil Ernerfeldt
A quick and dirty Space Invaders type game in Bevy, with attached tutorial.

This article is in-development and will be released in full form soon. It'll appear on Medium (my publisher likes that), with this as a the accompanyi

Herbert 17 Oct 18, 2022
A simple type safety solution for Bevy ECS.

?? Moonshine Kind A simple type safety solution for Bevy ECS. Overview An Entity is a generic way to reference entities within Bevy ECS: #[derive(Comp

null 8 Nov 3, 2023
Downdelving is an experimental roguelike written in Rust.

Downdelving Downdelving is an experimental roguelike written in Rust. It's built upon the base supplied by Bracket's Rust Roguelike Tutorial. It's a r

Nathan Douglas 1 Nov 6, 2021
An (experimental) chess tactics trainer with spaced repetition

better-tactics A chess tactics trainer that with spaced repetition. New puzzles will be shown to you from the lichess puzzle db, according to your cal

Caitlin Wilks 6 Oct 6, 2023
A safe, fast and cross-platform 2D component-based game framework written in rust

shura shura is a safe, fast and cross-platform 2D component-based game framework written in rust. shura helps you to manage big games with a component

Andri 28 Jan 17, 2023
Safe, fully-featured bindings to the Tracy profiler

Complete Rust bindings for the Tracy profiler. Getting Started Just add the following to your Cargo.toml: [dependencies.tracy] package = "tracy_full"

Shaye Garg 12 May 6, 2023
Rollback-safe implementations and utilities for Bevy Engine

bevy_roll_safe Rollback-safe implementations and utilities for Bevy Engine. Motivation Some of Bevy's features can't be used in a rollback context (wi

Johan Klokkhammer Helsing 3 Sep 17, 2023
Zero-cost and safe interface to UEFI firmware

ZFI – Zero-cost and safe interface to UEFI firmware ZFI is a Rust crate for writing a UEFI application with the following goals: Provides base APIs th

Ultima Microsystems 22 Sep 14, 2023
Rust-raytracer - 🔭 A simple ray tracer in Rust 🦀

rust-raytracer An implementation of a very simple raytracer based on Ray Tracing in One Weekend by Peter Shirley in Rust. I used this project to learn

David Singleton 159 Nov 28, 2022
Rust-and-opengl-lessons - Collection of example code for learning OpenGL in Rust

rust-and-opengl-lessons Project requires Rust 1.31 Collection of example code for learning OpenGL in Rust 00 - Setup 01 - Window 02 - OpenGL Context 0

Nerijus Arlauskas 348 Dec 11, 2022