6 releases (3 breaking)
0.4.0 | Sep 25, 2024 |
---|---|
0.3.0 | Sep 24, 2024 |
0.2.2 | Sep 22, 2024 |
0.1.0 | Sep 21, 2024 |
#346 in Math
479 downloads per month
58KB
1.5K
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;
let epsilon = 0.0001; // comparison threshold
assert!(line.is_flat(epsilon));
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_point(), (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_point(), (-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 Blade
s 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);
let epsilon = 0.0001; // comparison threshold
assert_eq!(inverted_circle.unpack(epsilon), cga2d::LineOrCircle::Circle {
cx: -3.0,
cy: -4.0,
r: 7.0
});
Operations
Wedge product
Antiwedge product
Left contraction
Negation
Dual
Scaling
Multivector
*
Scalar
->
Multivector
Scalar
*
Multivector
->
Multivector
Multivector
/
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.9MB
~17K SLoC