#geometric-algebra #2d #rotor #conformal-geometry

cga2d

2D Conformal Geometric Algebra primitives

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

#543 in Math

32 downloads per month

MIT/Apache

58KB
1.5K SLoC

cga2d

Crates.io Version docs.rs

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 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);
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

Geometric product

Geometric product by inverse

Addition & subtraction

Indexing

Indexing panics if the multivector type doesn't support the term. For a non-panicking alternative, see [Multivector::get()] and [Multivector::get_mut()].

Dependencies

~0.6–0.9MB
~17K SLoC