2个版本
0.1.2 | 2023年12月16日 |
---|---|
0.1.1 | 2023年12月15日 |
#539 in 数学
69KB
1.5K SLoC
简单:2D PGA!
简单,一个2D PGA库。
如果您不熟悉投影几何代数,请参阅
- https://www.youtube.com/watch?v=0i3ocLhbxJ4
- https://bivector.net/
- https://projectivegeometricalgebra.org/
否则,这个库就是它听起来那样。
这是我第一个发布的Rust crate,所以请多多包涵。如果数学或Rust代码有问题,请告诉我!
使用
使用此库应该相当简单,假设您对投影几何代数有基本的了解。
多矢量
Multivector<N>
是此库中最基本的单元。如果您来自传统的向量数学,可以将其视为一种变换矩阵。
Multivector<N>
结构体包含
- 标量
N
Vector<N>
Bivector<N>
Trivector<N>
注意泛型 'N
'。 N
必须实现 Float
。这是为了使此库具有通用性。
声明多矢量
可以将所有系数都设置为0的多矢量在一行中初始化
let my_multivector: Multivector<f32> = Multivector::zero();
有时您只想初始化具有单个阶定义的多矢量。可以这样做
// A multivector with only grade-0 coefficients:
let my_scalar = Multivector::from_scalar(scalar_number_here);
// A multivector with only grade-1 coefficients:
let my_vector = Multivector::from_vector(vector_defn_here);
// A multivector with only grade-2 coefficients:
let my_bivector = Multivector::from_bivector(bivector_defn_here);
// A multivector with only grade-3 coefficients:
let my_trivector = Multivector::from_trivector(trivector_defn_here);
另外,Vector
、Bivector
和 Trivector
结构体都有一个 to_multivector
函数
let my_vector = Vector{ e0: 1.0, e1: 1.0, e2: 1.0}.to_multivector();
let my_bivector = Bivector{ e01: 1.0, e20: 1.0, e12: 1.0}.to_multivector();
let my_trivctor = Trivector{ e012: 1.0 }.to_multivector();
向量
向量是投影几何代数中一级的几何对象。它由基向量e0、e1和e2构成,其中e02 == 0。
在2D PGA中,向量表示一条具有方向和大小的直线。
对于直线ax + by + c = 0
,相应的向量将是ae1 + be2 + ce0
。在代码中,这将看起来像
let example_line: Vector<f32> = Vector {
e0: number_c,
e1: number_a,
e2: number_b
};
双矢量
双矢量是二级的几何对象。在2D投影几何代数中,它是相交直线的交点。也就是说:双矢量表示一个2D点。
对于一个点(<x, y>)
,相应的双矢量将是xe20 + ye01 + 1e12
。请注意,基双矢量e12的值为1。在构造2D点时,e12双矢量应该归一化,使得这个系数为1。在代码中,这将看起来像
let example_bivector: Bivector<f32> = Bivector {
e01: x,
e20: y,
e12: 1.0
};
e12是投影坐标。当它为'0'时,你将表示一个无穷远点,有时简单地称为'方向'。
结构extras::point2d::Point2d
作为一个包装器存在,围绕双矢量,使处理2D欧几里得点更加直观。
三矢量
在2D投影几何代数中,三级k-向量被称为'伪标量'。它有一个单一的系数。包装它可能是不必要的,但我还是这样做了,以保持一致性。
这是一个三矢量的例子
let example_trivector: Trivector<f32> = Trivector { e012: 2.0 }
K-向量结构
诚然,这个库的这一部分最终变得几乎毫无用处。它被当作一个便利特性,但大多数几何对象在操作过程中都会转换为多矢量。尽管如此,它仍然保留,以防有人发现它有趣或有用。
KVector<N>
是一个枚举,封装了2D PGA中k-向量的每一个有效级别。
运算符
我已尽量包括所有2D PGA的基本运算符。
-
几何乘积
几何乘积是几何代数中最基本的运算,因此它自然存在于这里。任何两个k-向量之间的几何乘积将产生一个多矢量作为结果。同样,两个多矢量之间的几何乘积也可以计算。
请注意,大多数k-向量的几何乘积首先转换为多矢量,然后计算两个多矢量之间的几何乘积。对于某些常见的几何乘积(如两个向量之间的乘积),可能需要硬编码以进行未来的优化。
let mv1 = Multivector { ... }; let mv2 = Multivector { ... }; let product1 = mv1.geo(&mv2); let product2 = mv2.geo(&mv1); assert_ne!(product1, product2); // Should pass!
-
级数投影
多矢量上的级数投影只是输出与特定级别相关联的多矢量的分量。例如,对多矢量执行级别'1'的级数投影将给出其矢量分量。
这被实现为多矢量结构的一个成员函数,但结果发现这并不必要,因为你可以从多矢量中手动提取你想要的分量。该函数仍然保留。
let example_multivector = Multivector { ... }; // This syntax exists. let vector_component = example_multivector.grade_proj(1) .to_vector().unwrap(); // But it's really easier to just do this. let vector_component = example_multivector.vector;
-
外积
也称为'交点',因为它可以用来构建两条线的交点(这将是一个点)。两个k-向量 'A' 和 'B' 的外积:
A ^ B = C
,其中'A'的级别为'i','B'的级别为'j',将产生一个级别为'i+j'的'C'。它只是几何乘积后跟一个级数投影。如果认为有必要,可以硬编码常用的一些外积,这可能是未来优化的潜在来源。
let v1 = Vector { ... }; let v2 = Vector { ... }; let resulting_bivector = v1.wedge(&v2);
-
回归产品
两个点的“连接”将是一条直线。这种关系被回归产品精确地捕捉到。回归产品已经手动应用于两个双矢量。
注意:我尚未验证回归产品的正确性!
let bv1 = Bivector { ... }; let bv2 = Bivector { ... }; let joining_line = bv1.regressive(&bv2);
-
内积,左右收缩
内积当然是点积!左右收缩也存在,以防万一有人需要。
内积是两个k向量的几何积,级数投影以获取
|i-j|
分量。实际上,这几乎总是标量分量。这个操作符可能需要在未来的特定用例中进行优化。
let v1 = Vector { ... }; let v2 = Vector { ... }; let dot_product = v1.inner(&v2);
-
反向
通常用“箭头”符号表示,反向操作符在理论上会反转多向量的每个元素的基础分量顺序。在实践中,这会每两个级数翻转一次符号。
let example_multivector = Multivector { ... }; let example_reversed = example_multivector.reverse();
-
级数反演
与反向不同,级数反演会每级翻转一次符号。同样,它可以通过简单的调用执行。
let example_multivector = Multivector { ... }; let example_involuted = example_multivector.grade_involution();
-
模平方
向量和双矢量的模平方已实现。
let v1: Vector<f32> = Vector { ... }; let v1_norm: f32 = v1.magnitude_sqr() .sqrt(); // Take the sqrt if you want the magnitude.
-
归一化
向量和双矢量的归一化已实现。
let v1: Vector<f32> = Vector { ... }; // Note: This will always perform a square root operation. Norms are not cached by simply_2dpga. let v1_normalized = v1.normalized();
额外功能
那些不是严格2D PGA原语的物品已放置在“额外”crate中。
2D点
...
转子、电机和变压器
...
依赖项
~155KB