9 releases (3 major breaking)
| 3.0.0 | Aug 22, 2025 |
|---|---|
| 2.0.0 | Aug 21, 2025 |
| 1.0.0 | Jul 17, 2025 |
| 0.4.0 | Sep 25, 2024 |
| 0.1.0 | Sep 21, 2024 |
#444 in Math
443 downloads per month
85KB
2K
SLoC
cga2d
cga2d is a library for 2D Conformal Geometric Algebra with static types for various objects. It has traits for Multivector and Blade and types for blades of each grade, in addition to Rotor, Flector, and Rotoflector.
There is currently no general-purpose multivector type with all 16 components, but I am open to adding one in the future if there is use for one.
Read [the documentation][docs] for more details.
The scalar type is f64. I'm open to adding support for other scalar types, probably via feature flags. I'd prefer not to use generics, because that would greatly hinder ergonomics.
Known issues
- Not enough tests! I don't actually know if all the operations are implemented correctly.
lib.rs:
Conformal Geometric Algebra in 2D.
use cga2d::prelude::*;
let p1 = cga2d::point(1.0, 3.0);
let p2 = cga2d::point(-3.0, 5.0);
let line = p1 ^ p2 ^ NI;
assert!(line.is_flat());
assert_eq!(!(line ^ cga2d::point(-1.0, 4.0)), 0.0);
let circ = cga2d::circle(cga2d::point(3.0, 1.5), 3.0);
assert_eq!(circ.sandwich(NI).unpack().unwrap().finite(), Some([3.0, 1.5]));
let rot90_ccw: Rotor = cga2d::line(1.0, 1.0, 0.0) * cga2d::line(1.0, 0.0, 0.0);
assert_eq!(rot90_ccw.sandwich(cga2d::point(3.0, 4.0)).unpack().unwrap().finite(), Some([-4.0, 3.0]));
Multivector types
There is no unified multivector type. Instead, there is a Multivector
trait, implemented by several blades (which also implement the Blade
trait) and several rotoflectors.
Blades
| Blade type | Grade | Used to represent |
|---|---|---|
Scalar = [f64] |
0 | Scalar quantities |
Blade1 |
1 | Points, vectors, round points |
Blade2 |
2 | Point pairs, tangent points, flat points |
Blade3 |
3 | Circles (real & imaginary), lines |
Pseudoscalar |
4 | Pseudoscalar quantities |
Rotoflectors
| Rotoflector type | Subalgebra | Used to represent |
|---|---|---|
Rotor |
even | orientation-preserving conformal transformations |
Flector |
odd | non-orientation-preserving conformal transformations |
Rotoflector |
even or odd | conformal transformations |
Note that Rotoflector contains either even terms or odd terms. It is
not a general-purpose multivector.
There is no general-purpose multivector type.
Construction
The constants [NI] and [NO] contain 1-blades representing the point at
infinity and the origin respectively.
From components
All multivectors can be constructed directly via components.
let my_vector = Blade1 {
m: 0.0,
p: 0.0,
x: 3.0,
y: 4.0,
};
Helper functions
There are also several convenience functions built-in for constructing common multivectors, and these can be composed with operations.
// Type annotations are not required
let v: Blade1 = cga2d::vector(3.0, 4.0);
let center: Blade1 = cga2d::point(3.0, 4.0);
let real_circle: Blade3 = cga2d::circle(center, 7.0);
let imag_circle: Blade3 = cga2d::circle(center, -7.0);
let line: Blade3 = cga2d::line(3.0, 4.0, 2.0);
let point_pair: Blade2 = cga2d::point(3.0, 4.0) ^ NO;
let flat_point: Blade2 = cga2d::point(3.0, 4.0) ^ NI;
Additionally, all multivectors can be constructed by summing terms. Terms that cannot be represented by the multivector are discarded. I.e., the terms are grade-projected.
From terms
let vector: Blade1 = [
cga2d::Term::new(cga2d::Axes::X, 3.0),
cga2d::Term::new(cga2d::Axes::X, 4.0)
]
.into_iter()
.sum();
From blades
Rotoflectors can be constructed from Blades of the appropriate grade.
let center = cga2d::point(3.0, 4.0);
let circle = cga2d::circle(center, 7.0);
let circle_inversion = Flector::from(circle);
let central_inversion = Rotor::from(NI ^ NO);
let inverted_circle = central_inversion.sandwich(circle);
assert_eq!(inverted_circle.unpack(), cga2d::Circle::Circle {
cx: -3.0,
cy: -4.0,
r: 7.0,
ori: Orientation::Pos, // central inversion preserves orientation
});
Operations
Wedge product
Antiwedge product
Left contraction
Negation
Dual
Scaling
Multivector*Scalar->MultivectorScalar*Multivector->MultivectorMultivector/Scalar->Multivector
Geometric product
Multivector*Multivector->Rotor(where sum of grades is even)Multivector*Multivector->Flector(where sum of grades is odd)
Geometric product by inverse
Addition & subtraction
Multivector+Multivector->Multivector(must have same type)Multivector+Term->Multivector(panics if the multivector type doesn't support the term)Multivector-Term->Multivector(panics if the multivector type doesn't support the term)
Indexing
Indexing panics if the multivector type doesn't support the term. For a
non-panicking alternative, see [Multivector::get()] and
[Multivector::get_mut()].
Multivector[Axes]->Scalar(panics if the multivector type doesn't support the term)
Dependencies
~0.6–0.8MB
~17K SLoC