Skip to content

Commit 086e6e7

Browse files
committed
Doc + slerp + conversions.
1 parent 377f8b5 commit 086e6e7

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

66 files changed

+2073
-334
lines changed

Cargo.toml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,20 @@ path = "src/lib.rs"
1919
arbitrary = [ "quickcheck" ]
2020

2121
[dependencies]
22-
rustc-serialize = "0.3"
2322
typenum = "1.4"
2423
generic-array = "0.2"
2524
rand = "0.3"
2625
num-traits = "0.1"
2726
num-complex = "0.1"
2827
approx = "0.1"
2928
alga = "0.4"
29+
serde = "0.9"
30+
serde_derive = "0.9"
3031
# clippy = "*"
3132

3233
[dependencies.quickcheck]
3334
optional = true
3435
version = "0.3"
36+
37+
[dev-dependencies]
38+
serde_json = "0.9"

Makefile

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
all:
2-
cargo build --features "arbitrary"
2+
CARGO_INCREMENTAL=1 cargo build --features "arbitrary"
33

44
doc:
5-
cargo doc
5+
CARGO_INCREMENTAL=1 cargo doc
66

77
bench:
88
cargo bench
99

1010
test:
11-
cargo test --features "arbitrary"
11+
CARGO_INCREMENTAL=1 cargo test --features "arbitrary"

README.md

Lines changed: 4 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
<p align="center">
2+
<img src="http://nalgebra.org/img/logo_nalgebra.svg" alt="crates.io">
3+
</p>
14
<p align="center">
25
<a href="https://crates.io/crates/nalgebra">
36
<img src="http://meritbadge.herokuapp.com/nalgebra?style=flat-square" alt="crates.io">
@@ -8,75 +11,6 @@
811
</p>
912
<p align = "center">
1013
<strong>
11-
<a href="http://nalgebra.org/doc/nalgebra">Documentation</a> | <a href="http://users.nphysics.org">Forum</a>
14+
<a href="http://nalgebra.org">Users guide</a> | <a href="http://nalgebra.org/rustdoc/nalgebra/index.html">Documentation</a> | <a href="http://users.nphysics.org">Forum</a>
1215
</strong>
1316
</p>
14-
15-
nalgebra
16-
========
17-
18-
**nalgebra** is a low-dimensional linear algebra library written for Rust targeting:
19-
20-
* General-purpose linear algebra (still lacks a lot of features…)
21-
* Real time computer graphics.
22-
* Real time computer physics.
23-
24-
## Using **nalgebra**
25-
You will need the last stable build of the [rust compiler](http://www.rust-lang.org)
26-
and the official package manager: [cargo](https://github.com/rust-lang/cargo).
27-
28-
Simply add the following to your `Cargo.toml` file:
29-
30-
```.ignore
31-
[dependencies]
32-
nalgebra = "0.10.*"
33-
```
34-
35-
36-
All the functionality of **nalgebra** is grouped in one place: the root module `nalgebra::`. This
37-
module re-exports everything and includes free functions for all traits methods performing
38-
out-of-place operations.
39-
40-
Thus, you can import the whole prelude using:
41-
42-
```.ignore
43-
use nalgebra::*;
44-
```
45-
46-
However, the recommended way to use **nalgebra** is to import types and traits
47-
explicitly, and call free-functions using the `na::` prefix:
48-
49-
```.rust
50-
extern crate nalgebra as na;
51-
use na::{Vector3, Rotation3, Rotation};
52-
53-
fn main() {
54-
let a = Vector3::new(1.0f64, 1.0, 1.0);
55-
let mut b = Rotation3::new(na::zero());
56-
57-
b.append_rotation_mut(&a);
58-
59-
assert!(na::approx_eq(&na::rotation(&b), &a));
60-
}
61-
```
62-
63-
64-
## Features
65-
**nalgebra** is meant to be a general-purpose, low-dimensional, linear algebra library, with
66-
an optimized set of tools for computer graphics and physics. Those features include:
67-
68-
* Vectors with predefined static sizes: `Vector1`, `Vector2`, `Vector3`, `Vector4`, `Vector5`, `Vector6`.
69-
* Vector with a user-defined static size: `VectorN` (available only with the `generic_sizes` feature).
70-
* Points with static sizes: `Point1`, `Point2`, `Point3`, `Point4`, `Point5`, `Point6`.
71-
* Square matrices with static sizes: `Matrix1`, `Matrix2`, `Matrix3`, `Matrix4`, `Matrix5`, `Matrix6 `.
72-
* Rotation matrices: `Rotation2`, `Rotation3`
73-
* Quaternions: `Quaternion`, `Unit<Quaternion>`.
74-
* Unit-sized values (unit vectors, unit quaternions, etc.): `Unit<T>`, e.g., `Unit<Vector3<f32>>`.
75-
* Isometries (translation ⨯ rotation): `Isometry2`, `Isometry3`
76-
* Similarity transformations (translation ⨯ rotation ⨯ uniform scale): `Similarity2`, `Similarity3`.
77-
* 3D projections for computer graphics: `Persp3`, `PerspMatrix3`, `Ortho3`, `OrthoMatrix3`.
78-
* Dynamically sized heap-allocated vector: `DVector`.
79-
* Dynamically sized stack-allocated vectors with a maximum size: `DVector1` to `DVector6`.
80-
* Dynamically sized heap-allocated (square or rectangular) matrix: `DMatrix`.
81-
* Linear algebra and data analysis operators: `Covariance`, `Mean`, `qr`, `cholesky`.
82-
* Almost one trait per functionality: useful for generic programming.

examples/dimensional_genericity.rs

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
extern crate alga;
2+
extern crate nalgebra as na;
3+
4+
use alga::general::Real;
5+
use alga::linear::FiniteDimInnerSpace;
6+
use na::{Unit, ColumnVector, OwnedColumnVector, Vector2, Vector3};
7+
use na::storage::Storage;
8+
use na::dimension::{DimName, U1};
9+
10+
/// Reflects a vector wrt. the hyperplane with normal `plane_normal`.
11+
fn reflect_wrt_hyperplane_with_algebraic_genericity<V>(plane_normal: &Unit<V>, vector: &V) -> V
12+
where V: FiniteDimInnerSpace + Copy {
13+
let n = plane_normal.as_ref(); // Get the underlying vector of type `V`.
14+
*vector - *n * (n.dot(vector) * na::convert(2.0))
15+
}
16+
17+
18+
/// Reflects a vector wrt. the hyperplane with normal `plane_normal`.
19+
fn reflect_wrt_hyperplane_with_structural_genericity<N, D, S>(plane_normal: &Unit<ColumnVector<N, D, S>>,
20+
vector: &ColumnVector<N, D, S>)
21+
-> OwnedColumnVector<N, D, S::Alloc>
22+
where N: Real,
23+
D: DimName,
24+
S: Storage<N, D, U1> {
25+
let n = plane_normal.as_ref(); // Get the underlying V.
26+
vector - n * (n.dot(vector) * na::convert(2.0))
27+
}
28+
29+
/// Reflects a 2D vector wrt. the 2D line with normal `plane_normal`.
30+
fn reflect_wrt_hyperplane2<N>(plane_normal: &Unit<Vector2<N>>,
31+
vector: &Vector2<N>)
32+
-> Vector2<N>
33+
where N: Real {
34+
let n = plane_normal.as_ref(); // Get the underlying Vector2
35+
vector - n * (n.dot(vector) * na::convert(2.0))
36+
}
37+
38+
/// Reflects a 3D vector wrt. the 3D plane with normal `plane_normal`.
39+
/// /!\ This is an exact replicate of `reflect_wrt_hyperplane2, but for 3D.
40+
fn reflect_wrt_hyperplane3<N>(plane_normal: &Unit<Vector3<N>>,
41+
vector: &Vector3<N>)
42+
-> Vector3<N>
43+
where N: Real {
44+
let n = plane_normal.as_ref(); // Get the underlying Vector3
45+
vector - n * (n.dot(vector) * na::convert(2.0))
46+
}
47+
48+
49+
fn main() {
50+
let plane2 = Vector2::y_axis(); // 2D plane normal.
51+
let plane3 = Vector3::y_axis(); // 3D plane normal.
52+
53+
let v2 = Vector2::new(1.0, 2.0); // 2D vector to be reflected.
54+
let v3 = Vector3::new(1.0, 2.0, 3.0); // 3D vector to be reflected.
55+
56+
// We can call the same function for 2D and 3D.
57+
assert_eq!(reflect_wrt_hyperplane_with_algebraic_genericity(&plane2, &v2).y, -2.0);
58+
assert_eq!(reflect_wrt_hyperplane_with_algebraic_genericity(&plane3, &v3).y, -2.0);
59+
60+
assert_eq!(reflect_wrt_hyperplane_with_structural_genericity(&plane2, &v2).y, -2.0);
61+
assert_eq!(reflect_wrt_hyperplane_with_structural_genericity(&plane3, &v3).y, -2.0);
62+
63+
// Call each specific implementation depending on the dimension.
64+
assert_eq!(reflect_wrt_hyperplane2(&plane2, &v2).y, -2.0);
65+
assert_eq!(reflect_wrt_hyperplane3(&plane3, &v3).y, -2.0);
66+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#[macro_use]
2+
extern crate approx;
3+
extern crate nalgebra as na;
4+
5+
use std::f32;
6+
use na::{Vector2, Point2, Isometry2};
7+
8+
9+
fn use_dedicated_types() {
10+
let iso = Isometry2::new(Vector2::new(1.0, 1.0), f32::consts::PI);
11+
let pt = Point2::new(1.0, 0.0);
12+
let vec = Vector2::x();
13+
14+
let transformed_pt = iso * pt;
15+
let transformed_vec = iso * vec;
16+
17+
assert_relative_eq!(transformed_pt, Point2::new(0.0, 1.0));
18+
assert_relative_eq!(transformed_vec, Vector2::new(-1.0, 0.0));
19+
}
20+
21+
fn use_homogeneous_coordinates() {
22+
let iso = Isometry2::new(Vector2::new(1.0, 1.0), f32::consts::PI);
23+
let pt = Point2::new(1.0, 0.0);
24+
let vec = Vector2::x();
25+
26+
// Compute using homogeneous coordinates.
27+
let hom_iso = iso.to_homogeneous();
28+
let hom_pt = pt.to_homogeneous();
29+
let hom_vec = vec.to_homogeneous();
30+
31+
let hom_transformed_pt = hom_iso * hom_pt;
32+
let hom_transformed_vec = hom_iso * hom_vec;
33+
34+
// Convert back to the cartesian coordinates.
35+
let transformed_pt = Point2::from_homogeneous(hom_transformed_pt).unwrap();
36+
let transformed_vec = Vector2::from_homogeneous(hom_transformed_vec).unwrap();
37+
38+
assert_relative_eq!(transformed_pt, Point2::new(0.0, 1.0));
39+
assert_relative_eq!(transformed_vec, Vector2::new(-1.0, 0.0));
40+
}
41+
42+
fn main() {
43+
use_dedicated_types();
44+
use_homogeneous_coordinates();
45+
}

examples/identity.rs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
extern crate alga;
2+
extern crate nalgebra as na;
3+
4+
5+
use alga::linear::Transformation;
6+
use na::{Id, Vector3, Point3, Isometry3};
7+
8+
/*
9+
* Applies `n` times the transformation `t` to the vector `v` and sum each
10+
* intermediate value.
11+
*/
12+
fn complicated_algorithm<T>(v: &Vector3<f32>, t: &T, n: usize) -> Vector3<f32>
13+
where T: Transformation<Point3<f32>> {
14+
15+
let mut result = *v;
16+
17+
// Do lots of operations involving t.
18+
for _ in 0 .. n {
19+
result = v + t.transform_vector(&result);
20+
}
21+
22+
result
23+
}
24+
25+
26+
/*
27+
* The two following calls are equivalent in term of result.
28+
*/
29+
fn main() {
30+
let v = Vector3::new(1.0, 2.0, 3.0);
31+
32+
// The specialization generated by the compiler will do vector additions only.
33+
let result1 = complicated_algorithm(&v, &Id::new(), 100000);
34+
35+
// The specialization generated by the compiler will also include matrix multiplications.
36+
let iso = Isometry3::identity();
37+
let result2 = complicated_algorithm(&v, &iso, 100000);
38+
39+
// They both return the same result.
40+
assert!(result1 == Vector3::new(100001.0, 200002.0, 300003.0));
41+
assert!(result2 == Vector3::new(100001.0, 200002.0, 300003.0));
42+
}

examples/matrix_construction.rs

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
extern crate nalgebra as na;
2+
3+
use na::{Vector2, RowVector3, Matrix2x3, DMatrix};
4+
5+
6+
fn main() {
7+
// All the following matrices are equal but constructed in different ways.
8+
let m = Matrix2x3::new(1.1, 1.2, 1.3,
9+
2.1, 2.2, 2.3);
10+
11+
let m1 = Matrix2x3::from_rows(&[
12+
RowVector3::new(1.1, 1.2, 1.3),
13+
RowVector3::new(2.1, 2.2, 2.3)
14+
]);
15+
16+
let m2 = Matrix2x3::from_columns(&[
17+
Vector2::new(1.1, 2.1),
18+
Vector2::new(1.2, 2.2),
19+
Vector2::new(1.3, 2.3)
20+
]);
21+
22+
let m3 = Matrix2x3::from_row_slice(&[
23+
1.1, 1.2, 1.3,
24+
2.1, 2.2, 2.3
25+
]);
26+
27+
let m4 = Matrix2x3::from_column_slice(&[
28+
1.1, 2.1,
29+
1.2, 2.2,
30+
1.3, 2.3
31+
]);
32+
33+
let m5 = Matrix2x3::from_fn(|r, c| (r + 1) as f32 + (c + 1) as f32 / 10.0);
34+
35+
let m6 = Matrix2x3::from_iterator([ 1.1f32, 2.1, 1.2, 2.2, 1.3, 2.3 ].iter().cloned());
36+
37+
assert_eq!(m, m1); assert_eq!(m, m2); assert_eq!(m, m3);
38+
assert_eq!(m, m4); assert_eq!(m, m5); assert_eq!(m, m6);
39+
40+
// All the following matrices are equal but constructed in different ways.
41+
// This time, we used a dynamically-sized matrix to show the extra arguments
42+
// for the matrix shape.
43+
let dm = DMatrix::from_row_slice(4, 3, &[
44+
1.0, 0.0, 0.0,
45+
0.0, 1.0, 0.0,
46+
0.0, 0.0, 1.0,
47+
0.0, 0.0, 0.0
48+
]);
49+
50+
let dm1 = DMatrix::from_diagonal_element(4, 3, 1.0);
51+
let dm2 = DMatrix::identity(4, 3);
52+
let dm3 = DMatrix::from_fn(4, 3, |r, c| if r == c { 1.0 } else { 0.0 });
53+
let dm4 = DMatrix::from_iterator(4, 3, [
54+
// Components listed column-by-column.
55+
1.0, 0.0, 0.0, 0.0,
56+
0.0, 1.0, 0.0, 0.0,
57+
0.0, 0.0, 1.0, 0.0
58+
].iter().cloned());
59+
60+
assert_eq!(dm, dm1); assert_eq!(dm, dm2);
61+
assert_eq!(dm, dm3); assert_eq!(dm, dm4);
62+
}

examples/mvp.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#![allow(unused_variables)]
2+
3+
extern crate nalgebra as na;
4+
5+
use na::{Vector3, Point3, Isometry3, Perspective3};
6+
7+
fn main() {
8+
// Our object is translated along the x axis.
9+
let model = Isometry3::new(Vector3::x(), na::zero());
10+
11+
// Our camera looks toward the point (1.0, 0.0, 0.0).
12+
// It is located at (0.0, 0.0, 1.0).
13+
let eye = Point3::new(0.0, 0.0, 1.0);
14+
let target = Point3::new(1.0, 0.0, 0.0);
15+
let view = Isometry3::look_at_rh(&eye, &target, &Vector3::y());
16+
17+
// A perspective projection.
18+
let projection = Perspective3::new(16.0 / 9.0, 3.14 / 2.0, 1.0, 1000.0);
19+
20+
// The combination of the model with the view is still an isometry.
21+
let model_view = model * view;
22+
23+
// Convert everything to a `Matrix4` so that they can be combined.
24+
let mat_model_view = model_view.to_homogeneous();
25+
26+
// Combine everything.
27+
let model_view_projection = projection.as_matrix() * mat_model_view;
28+
}

0 commit comments

Comments
 (0)