├── .github
├── FUNDING.yml
└── workflows
│ └── nalgebra-ci-build.yml
├── .gitignore
├── CHANGELOG.md
├── Cargo.toml
├── LICENSE
├── README.md
├── benches
├── common
│ └── macros.rs
├── core
│ ├── matrix.rs
│ ├── mod.rs
│ └── vector.rs
├── geometry
│ ├── mod.rs
│ └── quaternion.rs
├── lib.rs
└── linalg
│ ├── bidiagonal.rs
│ ├── cholesky.rs
│ ├── eigen.rs
│ ├── full_piv_lu.rs
│ ├── hessenberg.rs
│ ├── lu.rs
│ ├── mod.rs
│ ├── qr.rs
│ ├── schur.rs
│ ├── solve.rs
│ ├── svd.rs
│ └── symmetric_eigen.rs
├── clippy.toml
├── examples
├── cargo
│ └── Cargo.toml
├── dimensional_genericity.rs
├── homogeneous_coordinates.rs
├── linear_system_resolution.rs
├── matrix_construction.rs
├── matrixcompare.rs
├── mvp.rs
├── point_construction.rs
├── raw_pointer.rs
├── reshaping.rs
├── scalar_genericity.rs
├── screen_to_view_coords.rs
├── transform_conversion.rs
├── transform_matrix4.rs
├── transform_vector_point.rs
├── transform_vector_point3.rs
├── transformation_pointer.rs
└── unit_wrapper.rs
├── nalgebra-glm
├── Cargo.toml
├── LICENSE
├── src
│ ├── aliases.rs
│ ├── common.rs
│ ├── constructors.rs
│ ├── exponential.rs
│ ├── ext
│ │ ├── matrix_clip_space.rs
│ │ ├── matrix_projection.rs
│ │ ├── matrix_relationnal.rs
│ │ ├── matrix_transform.rs
│ │ ├── mod.rs
│ │ ├── quaternion_common.rs
│ │ ├── quaternion_geometric.rs
│ │ ├── quaternion_relational.rs
│ │ ├── quaternion_transform.rs
│ │ ├── quaternion_trigonometric.rs
│ │ ├── scalar_common.rs
│ │ ├── scalar_constants.rs
│ │ ├── vector_common.rs
│ │ └── vector_relational.rs
│ ├── geometric.rs
│ ├── gtc
│ │ ├── bitfield.rs
│ │ ├── constants.rs
│ │ ├── epsilon.rs
│ │ ├── integer.rs
│ │ ├── matrix_access.rs
│ │ ├── matrix_inverse.rs
│ │ ├── mod.rs
│ │ ├── packing.rs
│ │ ├── quaternion.rs
│ │ ├── reciprocal.rs
│ │ ├── round.rs
│ │ ├── type_ptr.rs
│ │ └── ulp.rs
│ ├── gtx
│ │ ├── component_wise.rs
│ │ ├── euler_angles.rs
│ │ ├── exterior_product.rs
│ │ ├── handed_coordinate_space.rs
│ │ ├── matrix_cross_product.rs
│ │ ├── matrix_operation.rs
│ │ ├── mod.rs
│ │ ├── norm.rs
│ │ ├── normal.rs
│ │ ├── normalize_dot.rs
│ │ ├── quaternion.rs
│ │ ├── rotate_normalized_axis.rs
│ │ ├── rotate_vector.rs
│ │ ├── transform.rs
│ │ ├── transform2.rs
│ │ ├── transform2d.rs
│ │ ├── vector_angle.rs
│ │ └── vector_query.rs
│ ├── integer.rs
│ ├── lib.rs
│ ├── matrix.rs
│ ├── packing.rs
│ ├── traits.rs
│ ├── trigonometric.rs
│ └── vector_relational.rs
└── tests
│ └── lib.rs
├── nalgebra-lapack
├── CHANGELOG.md
├── Cargo.toml
├── LICENSE
├── Makefile
├── README.md
├── benches
│ ├── lib.rs
│ └── linalg
│ │ ├── hessenberg.rs
│ │ ├── lu.rs
│ │ ├── mod.rs
│ │ └── qr.rs
├── src
│ ├── cholesky.rs
│ ├── eigen.rs
│ ├── generalized_eigenvalues.rs
│ ├── hessenberg.rs
│ ├── lapack_check.rs
│ ├── lib.rs
│ ├── lu.rs
│ ├── qr.rs
│ ├── qz.rs
│ ├── schur.rs
│ ├── svd.rs
│ └── symmetric_eigen.rs
└── tests
│ ├── lib.rs
│ └── linalg
│ ├── cholesky.rs
│ ├── complex_eigen.rs
│ ├── generalized_eigenvalues.rs
│ ├── hessenberg.rs
│ ├── lu.rs
│ ├── mod.rs
│ ├── qr.rs
│ ├── qz.rs
│ ├── real_eigensystem.rs
│ ├── schur.rs
│ ├── svd.rs
│ └── symmetric_eigen.rs
├── nalgebra-macros
├── Cargo.toml
├── LICENSE
└── src
│ ├── lib.rs
│ ├── matrix_vector_impl.rs
│ └── stack_impl.rs
├── nalgebra-sparse
├── Cargo.toml
├── LICENSE
├── src
│ ├── convert
│ │ ├── impl_std_ops.rs
│ │ ├── mod.rs
│ │ └── serial.rs
│ ├── coo.rs
│ ├── coo
│ │ └── coo_serde.rs
│ ├── cs.rs
│ ├── csc.rs
│ ├── csc
│ │ └── csc_serde.rs
│ ├── csr.rs
│ ├── csr
│ │ └── csr_serde.rs
│ ├── factorization
│ │ ├── cholesky.rs
│ │ └── mod.rs
│ ├── io
│ │ ├── matrix_market.pest
│ │ ├── matrix_market.rs
│ │ └── mod.rs
│ ├── lib.rs
│ ├── matrixcompare.rs
│ ├── ops
│ │ ├── impl_std_ops.rs
│ │ ├── mod.rs
│ │ └── serial
│ │ │ ├── cs.rs
│ │ │ ├── csc.rs
│ │ │ ├── csr.rs
│ │ │ ├── mod.rs
│ │ │ └── pattern.rs
│ ├── pattern.rs
│ ├── pattern
│ │ └── pattern_serde.rs
│ ├── proptest.rs
│ └── utils.rs
└── tests
│ ├── common
│ └── mod.rs
│ ├── serde.rs
│ ├── unit.rs
│ └── unit_tests
│ ├── cholesky.proptest-regressions
│ ├── cholesky.rs
│ ├── convert_serial.proptest-regressions
│ ├── convert_serial.rs
│ ├── coo.rs
│ ├── csc.proptest-regressions
│ ├── csc.rs
│ ├── csr.rs
│ ├── matrix_market.rs
│ ├── mod.rs
│ ├── ops.proptest-regressions
│ ├── ops.rs
│ ├── pattern.rs
│ ├── proptest.rs
│ └── test_data_examples.rs
├── rustfmt.toml
├── src
├── base
│ ├── alias.rs
│ ├── alias_slice.rs
│ ├── alias_view.rs
│ ├── allocator.rs
│ ├── array_storage.rs
│ ├── blas.rs
│ ├── blas_uninit.rs
│ ├── cg.rs
│ ├── componentwise.rs
│ ├── constraint.rs
│ ├── construction.rs
│ ├── construction_view.rs
│ ├── conversion.rs
│ ├── coordinates.rs
│ ├── default_allocator.rs
│ ├── dimension.rs
│ ├── edition.rs
│ ├── helper.rs
│ ├── indexing.rs
│ ├── interpolation.rs
│ ├── iter.rs
│ ├── matrix.rs
│ ├── matrix_simba.rs
│ ├── matrix_view.rs
│ ├── min_max.rs
│ ├── mod.rs
│ ├── norm.rs
│ ├── ops.rs
│ ├── par_iter.rs
│ ├── properties.rs
│ ├── rkyv_wrappers.rs
│ ├── scalar.rs
│ ├── statistics.rs
│ ├── storage.rs
│ ├── swizzle.rs
│ ├── uninit.rs
│ ├── unit.rs
│ └── vec_storage.rs
├── debug
│ ├── mod.rs
│ ├── random_orthogonal.rs
│ └── random_sdp.rs
├── geometry
│ ├── abstract_rotation.rs
│ ├── dual_quaternion.rs
│ ├── dual_quaternion_construction.rs
│ ├── dual_quaternion_conversion.rs
│ ├── dual_quaternion_ops.rs
│ ├── isometry.rs
│ ├── isometry_alias.rs
│ ├── isometry_construction.rs
│ ├── isometry_conversion.rs
│ ├── isometry_interpolation.rs
│ ├── isometry_ops.rs
│ ├── isometry_simba.rs
│ ├── mod.rs
│ ├── op_macros.rs
│ ├── orthographic.rs
│ ├── perspective.rs
│ ├── point.rs
│ ├── point_alias.rs
│ ├── point_construction.rs
│ ├── point_conversion.rs
│ ├── point_coordinates.rs
│ ├── point_ops.rs
│ ├── point_simba.rs
│ ├── quaternion.rs
│ ├── quaternion_construction.rs
│ ├── quaternion_conversion.rs
│ ├── quaternion_coordinates.rs
│ ├── quaternion_ops.rs
│ ├── quaternion_simba.rs
│ ├── reflection.rs
│ ├── reflection_alias.rs
│ ├── rotation.rs
│ ├── rotation_alias.rs
│ ├── rotation_construction.rs
│ ├── rotation_conversion.rs
│ ├── rotation_interpolation.rs
│ ├── rotation_ops.rs
│ ├── rotation_simba.rs
│ ├── rotation_specialization.rs
│ ├── scale.rs
│ ├── scale_alias.rs
│ ├── scale_construction.rs
│ ├── scale_conversion.rs
│ ├── scale_coordinates.rs
│ ├── scale_ops.rs
│ ├── scale_simba.rs
│ ├── similarity.rs
│ ├── similarity_alias.rs
│ ├── similarity_construction.rs
│ ├── similarity_conversion.rs
│ ├── similarity_ops.rs
│ ├── similarity_simba.rs
│ ├── swizzle.rs
│ ├── transform.rs
│ ├── transform_alias.rs
│ ├── transform_construction.rs
│ ├── transform_conversion.rs
│ ├── transform_ops.rs
│ ├── transform_simba.rs
│ ├── translation.rs
│ ├── translation_alias.rs
│ ├── translation_construction.rs
│ ├── translation_conversion.rs
│ ├── translation_coordinates.rs
│ ├── translation_ops.rs
│ ├── translation_simba.rs
│ ├── unit_complex.rs
│ ├── unit_complex_construction.rs
│ ├── unit_complex_conversion.rs
│ ├── unit_complex_ops.rs
│ └── unit_complex_simba.rs
├── io
│ ├── matrix_market.pest
│ ├── matrix_market.rs
│ └── mod.rs
├── lib.rs
├── linalg
│ ├── balancing.rs
│ ├── bidiagonal.rs
│ ├── cholesky.rs
│ ├── col_piv_qr.rs
│ ├── convolution.rs
│ ├── decomposition.rs
│ ├── determinant.rs
│ ├── eigen.rs
│ ├── exp.rs
│ ├── full_piv_lu.rs
│ ├── givens.rs
│ ├── hessenberg.rs
│ ├── householder.rs
│ ├── inverse.rs
│ ├── lu.rs
│ ├── mod.rs
│ ├── permutation_sequence.rs
│ ├── pow.rs
│ ├── qr.rs
│ ├── schur.rs
│ ├── solve.rs
│ ├── svd.rs
│ ├── svd2.rs
│ ├── svd3.rs
│ ├── symmetric_eigen.rs
│ ├── symmetric_tridiagonal.rs
│ └── udu.rs
├── proptest
│ └── mod.rs
├── sparse
│ ├── cs_matrix.rs
│ ├── cs_matrix_cholesky.rs
│ ├── cs_matrix_conversion.rs
│ ├── cs_matrix_ops.rs
│ ├── cs_matrix_solve.rs
│ ├── cs_utils.rs
│ └── mod.rs
└── third_party
│ ├── alga
│ ├── alga_dual_quaternion.rs
│ ├── alga_isometry.rs
│ ├── alga_matrix.rs
│ ├── alga_point.rs
│ ├── alga_quaternion.rs
│ ├── alga_rotation.rs
│ ├── alga_similarity.rs
│ ├── alga_transform.rs
│ ├── alga_translation.rs
│ ├── alga_unit_complex.rs
│ └── mod.rs
│ ├── glam
│ ├── common
│ │ ├── glam_isometry.rs
│ │ ├── glam_matrix.rs
│ │ ├── glam_point.rs
│ │ ├── glam_quaternion.rs
│ │ ├── glam_rotation.rs
│ │ ├── glam_similarity.rs
│ │ ├── glam_translation.rs
│ │ └── glam_unit_complex.rs
│ ├── mod.rs
│ ├── v014
│ │ └── mod.rs
│ ├── v015
│ │ └── mod.rs
│ ├── v016
│ │ └── mod.rs
│ ├── v017
│ │ └── mod.rs
│ ├── v018
│ │ └── mod.rs
│ ├── v019
│ │ └── mod.rs
│ ├── v020
│ │ └── mod.rs
│ ├── v021
│ │ └── mod.rs
│ ├── v022
│ │ └── mod.rs
│ ├── v023
│ │ └── mod.rs
│ ├── v024
│ │ └── mod.rs
│ ├── v025
│ │ └── mod.rs
│ ├── v027
│ │ └── mod.rs
│ ├── v028
│ │ └── mod.rs
│ ├── v029
│ │ └── mod.rs
│ └── v030
│ │ └── mod.rs
│ ├── mint
│ ├── mint_matrix.rs
│ ├── mint_point.rs
│ ├── mint_quaternion.rs
│ ├── mint_rotation.rs
│ └── mod.rs
│ └── mod.rs
└── tests
├── core
├── blas.rs
├── cg.rs
├── conversion.rs
├── edition.rs
├── empty.rs
├── helper.rs
├── macros.rs
├── matrix.rs
├── matrix_view.rs
├── matrixcompare.rs
├── mint.rs
├── mod.rs
├── reshape.rs
├── rkyv.rs
├── serde.rs
└── variance.rs
├── geometry
├── dual_quaternion.rs
├── isometry.rs
├── mod.rs
├── point.rs
├── projection.rs
├── quaternion.rs
├── rotation.rs
├── similarity.rs
└── unit_complex.rs
├── lib.rs
├── linalg
├── balancing.rs
├── bidiagonal.rs
├── cholesky.rs
├── col_piv_qr.rs
├── convolution.rs
├── eigen.rs
├── exp.rs
├── full_piv_lu.rs
├── hessenberg.rs
├── inverse.rs
├── lu.rs
├── mod.rs
├── pow.rs
├── qr.rs
├── schur.rs
├── solve.rs
├── svd.rs
├── tridiagonal.rs
└── udu.rs
├── macros
├── matrix.rs
├── mod.rs
├── stack.rs
└── trybuild
│ ├── dmatrix_mismatched_dimensions.rs
│ ├── dmatrix_mismatched_dimensions.stderr
│ ├── matrix_mismatched_dimensions.rs
│ ├── matrix_mismatched_dimensions.stderr
│ ├── stack_empty_col.rs
│ ├── stack_empty_col.stderr
│ ├── stack_empty_row.rs
│ ├── stack_empty_row.stderr
│ ├── stack_incompatible_block_dimensions.rs
│ ├── stack_incompatible_block_dimensions.stderr
│ ├── stack_incompatible_block_dimensions2.rs
│ └── stack_incompatible_block_dimensions2.stderr
├── proptest
└── mod.rs
└── sparse
├── cs_cholesky.rs
├── cs_construction.rs
├── cs_conversion.rs
├── cs_matrix.rs
├── cs_matrix_market.rs
├── cs_ops.rs
├── cs_solve.rs
└── mod.rs
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: [ "dimforge" ] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
4 | patreon: # Replace with a single Patreon username
5 | open_collective: # Replace with a single Open Collective username
6 | ko_fi: # Replace with a single Ko-fi username
7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9 | liberapay: # Replace with a single Liberapay username
10 | issuehunt: # Replace with a single IssueHunt username
11 | otechie: # Replace with a single Otechie username
12 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
13 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.swp
2 | *.html
3 | doc
4 | lib
5 | TODO
6 | target/
7 | Cargo.lock
8 | *.orig
9 | *.swo
10 | site/
11 | .vscode/
12 | .idea/
13 | proptest-regressions
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | Users guide | Documentation
18 |
19 |
20 |
21 | -----
22 |
23 |
24 | Linear algebra library
25 | for the Rust programming language.
26 |
27 |
28 | -----
29 |
--------------------------------------------------------------------------------
/benches/core/mod.rs:
--------------------------------------------------------------------------------
1 | pub use self::matrix::matrix;
2 | pub use self::vector::vector;
3 |
4 | mod matrix;
5 | mod vector;
6 |
--------------------------------------------------------------------------------
/benches/geometry/mod.rs:
--------------------------------------------------------------------------------
1 | pub use self::quaternion::quaternion;
2 |
3 | mod quaternion;
4 |
--------------------------------------------------------------------------------
/benches/geometry/quaternion.rs:
--------------------------------------------------------------------------------
1 | use na::{Quaternion, UnitQuaternion, Vector3};
2 | use rand::Rng;
3 | use rand_isaac::IsaacRng;
4 | use std::ops::{Add, Div, Mul, Sub};
5 |
6 | #[path = "../common/macros.rs"]
7 | mod macros;
8 |
9 | bench_binop!(quaternion_add_q, Quaternion, Quaternion, add);
10 | bench_binop!(quaternion_sub_q, Quaternion, Quaternion, sub);
11 | bench_binop!(quaternion_mul_q, Quaternion, Quaternion, mul);
12 |
13 | bench_binop!(
14 | unit_quaternion_mul_v,
15 | UnitQuaternion,
16 | Vector3,
17 | mul
18 | );
19 |
20 | bench_binop!(quaternion_mul_s, Quaternion, f32, mul);
21 | bench_binop!(quaternion_div_s, Quaternion, f32, div);
22 |
23 | bench_unop!(quaternion_inv, Quaternion, try_inverse);
24 | bench_unop!(unit_quaternion_inv, UnitQuaternion, inverse);
25 |
26 | // bench_unop_self!(quaternion_conjugate, Quaternion, conjugate);
27 | // bench_unop!(quaternion_normalize, Quaternion, normalize);
28 |
29 | criterion_group!(
30 | quaternion,
31 | quaternion_add_q,
32 | quaternion_sub_q,
33 | quaternion_mul_q,
34 | unit_quaternion_mul_v,
35 | quaternion_mul_s,
36 | quaternion_div_s,
37 | quaternion_inv,
38 | unit_quaternion_inv
39 | );
40 |
--------------------------------------------------------------------------------
/benches/lib.rs:
--------------------------------------------------------------------------------
1 | #![allow(unused_macros)]
2 |
3 | extern crate nalgebra as na;
4 | extern crate rand_package as rand;
5 |
6 | #[macro_use]
7 | extern crate criterion;
8 |
9 | use na::DMatrix;
10 | use rand::Rng;
11 | use rand_isaac::IsaacRng;
12 |
13 | pub mod core;
14 | pub mod geometry;
15 | pub mod linalg;
16 |
17 | fn reproducible_dmatrix(nrows: usize, ncols: usize) -> DMatrix {
18 | use rand::SeedableRng;
19 | let mut rng = IsaacRng::seed_from_u64(0);
20 | DMatrix::::from_fn(nrows, ncols, |_, _| rng.gen())
21 | }
22 |
23 | criterion_main!(
24 | core::matrix,
25 | core::vector,
26 | geometry::quaternion,
27 | linalg::bidiagonal,
28 | linalg::cholesky,
29 | linalg::full_piv_lu,
30 | linalg::hessenberg,
31 | linalg::lu,
32 | linalg::qr,
33 | linalg::schur,
34 | linalg::solve,
35 | linalg::svd,
36 | linalg::symmetric_eigen,
37 | );
38 |
--------------------------------------------------------------------------------
/benches/linalg/eigen.rs:
--------------------------------------------------------------------------------
1 | use na::{DMatrix, Eigen};
2 |
3 | fn eigen_100x100(bh: &mut criterion::Criterion) {
4 | let m = DMatrix::::new_random(100, 100);
5 |
6 | bh.bench_function("eigen_100x100", move |bh| bh.iter(|| Eigen::new(m.clone(), 1.0e-7, 0)));
7 | }
8 |
9 | fn eigen_500x500(bh: &mut criterion::Criterion) {
10 | let m = DMatrix::::new_random(500, 500);
11 |
12 | bh.bench_function("eigen_500x500", move |bh| bh.iter(|| Eigen::new(m.clone(), 1.0e-7, 0)));
13 | }
14 |
15 | fn eigenvalues_100x100(bh: &mut criterion::Criterion) {
16 | let m = DMatrix::::new_random(100, 100);
17 |
18 | bh.bench_function("eigenvalues_100x100", move |bh| bh.iter(|| m.clone().eigenvalues(1.0e-7, 0)));
19 | }
20 |
21 | fn eigenvalues_500x500(bh: &mut criterion::Criterion) {
22 | let m = DMatrix::::new_random(500, 500);
23 |
24 | bh.bench_function("eigenvalues_500x500", move |bh| bh.iter(|| m.clone().eigenvalues(1.0e-7, 0)));
25 | }
26 |
27 | criterion_group!(eigen,
28 | eigen_100x100,
29 | // eigen_500x500,
30 | eigenvalues_100x100,
31 | // eigenvalues_500x500
32 | );
33 |
--------------------------------------------------------------------------------
/benches/linalg/mod.rs:
--------------------------------------------------------------------------------
1 | pub use self::bidiagonal::bidiagonal;
2 | pub use self::cholesky::cholesky;
3 | pub use self::full_piv_lu::full_piv_lu;
4 | pub use self::hessenberg::hessenberg;
5 | pub use self::lu::lu;
6 | pub use self::qr::qr;
7 | pub use self::schur::schur;
8 | pub use self::solve::solve;
9 | pub use self::svd::svd;
10 | pub use self::symmetric_eigen::symmetric_eigen;
11 |
12 | mod bidiagonal;
13 | mod cholesky;
14 | mod full_piv_lu;
15 | mod hessenberg;
16 | mod lu;
17 | mod qr;
18 | mod schur;
19 | mod solve;
20 | mod svd;
21 | mod symmetric_eigen;
22 | // mod eigen;
23 |
--------------------------------------------------------------------------------
/benches/linalg/symmetric_eigen.rs:
--------------------------------------------------------------------------------
1 | use na::{Matrix4, SymmetricEigen};
2 |
3 | fn symmetric_eigen_decompose_4x4(bh: &mut criterion::Criterion) {
4 | let m = Matrix4::::new_random();
5 | bh.bench_function("symmetric_eigen_decompose_4x4", move |bh| {
6 | bh.iter(|| std::hint::black_box(SymmetricEigen::new(m.clone())))
7 | });
8 | }
9 |
10 | fn symmetric_eigen_decompose_10x10(bh: &mut criterion::Criterion) {
11 | let m = crate::reproducible_dmatrix(10, 10);
12 | bh.bench_function("symmetric_eigen_decompose_10x10", move |bh| {
13 | bh.iter(|| std::hint::black_box(SymmetricEigen::new(m.clone())))
14 | });
15 | }
16 |
17 | fn symmetric_eigen_decompose_100x100(bh: &mut criterion::Criterion) {
18 | let m = crate::reproducible_dmatrix(100, 100);
19 | bh.bench_function("symmetric_eigen_decompose_100x100", move |bh| {
20 | bh.iter(|| std::hint::black_box(SymmetricEigen::new(m.clone())))
21 | });
22 | }
23 |
24 | fn symmetric_eigen_decompose_200x200(bh: &mut criterion::Criterion) {
25 | let m = crate::reproducible_dmatrix(200, 200);
26 | bh.bench_function("symmetric_eigen_decompose_200x200", move |bh| {
27 | bh.iter(|| std::hint::black_box(SymmetricEigen::new(m.clone())))
28 | });
29 | }
30 |
31 | criterion_group!(
32 | symmetric_eigen,
33 | symmetric_eigen_decompose_4x4,
34 | symmetric_eigen_decompose_10x10,
35 | symmetric_eigen_decompose_100x100,
36 | symmetric_eigen_decompose_200x200
37 | );
38 |
--------------------------------------------------------------------------------
/clippy.toml:
--------------------------------------------------------------------------------
1 | too-many-arguments-threshold = 8
2 | type-complexity-threshold = 675
3 |
--------------------------------------------------------------------------------
/examples/cargo/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "example-using-nalgebra"
3 | version = "0.0.0"
4 | authors = ["You"]
5 |
6 | [dependencies]
7 | nalgebra = "0.33.0"
8 |
9 | [[bin]]
10 | name = "example"
11 | path = "./example.rs"
12 |
--------------------------------------------------------------------------------
/examples/dimensional_genericity.rs:
--------------------------------------------------------------------------------
1 | extern crate nalgebra as na;
2 |
3 | use na::allocator::Allocator;
4 | use na::dimension::Dim;
5 | use na::{DefaultAllocator, OVector, RealField, Unit, Vector2, Vector3};
6 |
7 | /// Reflects a vector wrt. the hyperplane with normal `plane_normal`.
8 | fn reflect_wrt_hyperplane_with_dimensional_genericity(
9 | plane_normal: &Unit>,
10 | vector: &OVector,
11 | ) -> OVector
12 | where
13 | T: RealField,
14 | D: Dim,
15 | DefaultAllocator: Allocator,
16 | {
17 | let n = plane_normal.as_ref(); // Get the underlying V.
18 | vector - n * (n.dot(vector) * na::convert(2.0))
19 | }
20 |
21 | /// Reflects a 2D vector wrt. the 2D line with normal `plane_normal`.
22 | fn reflect_wrt_hyperplane2(plane_normal: &Unit>, vector: &Vector2) -> Vector2
23 | where
24 | T: RealField,
25 | {
26 | let n = plane_normal.as_ref(); // Get the underlying Vector2
27 | vector - n * (n.dot(vector) * na::convert(2.0))
28 | }
29 |
30 | /// Reflects a 3D vector wrt. the 3D plane with normal `plane_normal`.
31 | /// /!\ This is an exact replicate of `reflect_wrt_hyperplane2`, but for 3D.
32 | fn reflect_wrt_hyperplane3(plane_normal: &Unit>, vector: &Vector3) -> Vector3
33 | where
34 | T: RealField,
35 | {
36 | let n = plane_normal.as_ref(); // Get the underlying Vector3
37 | vector - n * (n.dot(vector) * na::convert(2.0))
38 | }
39 |
40 | fn main() {
41 | let plane2 = Vector2::y_axis(); // 2D plane normal.
42 | let plane3 = Vector3::y_axis(); // 3D plane normal.
43 |
44 | let v2 = Vector2::new(1.0, 2.0); // 2D vector to be reflected.
45 | let v3 = Vector3::new(1.0, 2.0, 3.0); // 3D vector to be reflected.
46 |
47 | // We can call the same function for 2D and 3D.
48 | assert_eq!(
49 | reflect_wrt_hyperplane_with_dimensional_genericity(&plane2, &v2).y,
50 | -2.0
51 | );
52 | assert_eq!(
53 | reflect_wrt_hyperplane_with_dimensional_genericity(&plane3, &v3).y,
54 | -2.0
55 | );
56 |
57 | // Call each specific implementation depending on the dimension.
58 | assert_eq!(reflect_wrt_hyperplane2(&plane2, &v2).y, -2.0);
59 | assert_eq!(reflect_wrt_hyperplane3(&plane3, &v3).y, -2.0);
60 | }
61 |
--------------------------------------------------------------------------------
/examples/homogeneous_coordinates.rs:
--------------------------------------------------------------------------------
1 | #[macro_use]
2 | extern crate approx;
3 | extern crate nalgebra as na;
4 |
5 | use na::{Isometry2, Point2, Vector2};
6 | use std::f32;
7 |
8 | fn use_dedicated_types() {
9 | let iso = Isometry2::new(Vector2::new(1.0, 1.0), f32::consts::PI);
10 | let pt = Point2::new(1.0, 0.0);
11 | let vec = Vector2::x();
12 |
13 | let transformed_pt = iso * pt;
14 | let transformed_vec = iso * vec;
15 |
16 | assert_relative_eq!(transformed_pt, Point2::new(0.0, 1.0));
17 | assert_relative_eq!(transformed_vec, Vector2::new(-1.0, 0.0));
18 | }
19 |
20 | fn use_homogeneous_coordinates() {
21 | let iso = Isometry2::new(Vector2::new(1.0, 1.0), f32::consts::PI);
22 | let pt = Point2::new(1.0, 0.0);
23 | let vec = Vector2::x();
24 |
25 | // Compute using homogeneous coordinates.
26 | let hom_iso = iso.to_homogeneous();
27 | let hom_pt = pt.to_homogeneous();
28 | let hom_vec = vec.to_homogeneous();
29 |
30 | let hom_transformed_pt = hom_iso * hom_pt;
31 | let hom_transformed_vec = hom_iso * hom_vec;
32 |
33 | // Convert back to the cartesian coordinates.
34 | let transformed_pt = Point2::from_homogeneous(hom_transformed_pt).unwrap();
35 | let transformed_vec = Vector2::from_homogeneous(hom_transformed_vec).unwrap();
36 |
37 | assert_relative_eq!(transformed_pt, Point2::new(0.0, 1.0));
38 | assert_relative_eq!(transformed_vec, Vector2::new(-1.0, 0.0));
39 | }
40 |
41 | fn main() {
42 | use_dedicated_types();
43 | use_homogeneous_coordinates();
44 | }
45 |
--------------------------------------------------------------------------------
/examples/linear_system_resolution.rs:
--------------------------------------------------------------------------------
1 | #![cfg_attr(rustfmt, rustfmt_skip)]
2 | #[macro_use]
3 | extern crate approx; // for assert_relative_eq
4 | extern crate nalgebra as na;
5 | use na::{Matrix4, Matrix4x3, Vector4};
6 |
7 | fn main() {
8 | let a = Matrix4::new(
9 | 1.0, 1.0, 2.0, -5.0,
10 | 2.0, 5.0, -1.0, -9.0,
11 | 2.0, 1.0, -1.0, 3.0,
12 | 1.0, 3.0, 2.0, 7.0,
13 | );
14 | let mut b = Vector4::new(3.0, -3.0, -11.0, -5.0);
15 | let decomp = a.lu();
16 | let x = decomp.solve(&b).expect("Linear resolution failed.");
17 | assert_relative_eq!(a * x, b);
18 |
19 | /*
20 | * It is possible to perform the resolution in-place.
21 | * This is particularly useful to avoid allocations when
22 | * `b` is a `DVector` or a `DMatrix`.
23 | */
24 | assert!(decomp.solve_mut(&mut b), "Linear resolution failed.");
25 | assert_relative_eq!(x, b);
26 |
27 | /*
28 | * It is possible to solve multiple systems
29 | * simultaneously by using a matrix for `b`.
30 | */
31 | let b = Matrix4x3::new(
32 | 3.0, 2.0, 0.0,
33 | -3.0, 0.0, 0.0,
34 | -11.0, 5.0, -3.0,
35 | -5.0, 10.0, 4.0,
36 | );
37 | let x = decomp.solve(&b).expect("Linear resolution failed.");
38 | assert_relative_eq!(a * x, b);
39 | }
40 |
--------------------------------------------------------------------------------
/examples/matrix_construction.rs:
--------------------------------------------------------------------------------
1 | extern crate nalgebra as na;
2 |
3 | use na::{DMatrix, Matrix2x3, RowVector3, Vector2};
4 |
5 | fn main() {
6 | // All the following matrices are equal but constructed in different ways.
7 | let m = Matrix2x3::new(1.1, 1.2, 1.3, 2.1, 2.2, 2.3);
8 |
9 | let m1 = Matrix2x3::from_rows(&[
10 | RowVector3::new(1.1, 1.2, 1.3),
11 | RowVector3::new(2.1, 2.2, 2.3),
12 | ]);
13 |
14 | let m2 = Matrix2x3::from_columns(&[
15 | Vector2::new(1.1, 2.1),
16 | Vector2::new(1.2, 2.2),
17 | Vector2::new(1.3, 2.3),
18 | ]);
19 |
20 | let m3 = Matrix2x3::from_row_slice(&[1.1, 1.2, 1.3, 2.1, 2.2, 2.3]);
21 |
22 | let m4 = Matrix2x3::from_column_slice(&[1.1, 2.1, 1.2, 2.2, 1.3, 2.3]);
23 |
24 | let m5 = Matrix2x3::from_fn(|r, c| (r + 1) as f32 + (c + 1) as f32 / 10.0);
25 |
26 | let m6 = Matrix2x3::from_iterator([1.1f32, 2.1, 1.2, 2.2, 1.3, 2.3].iter().cloned());
27 |
28 | assert_eq!(m, m1);
29 | assert_eq!(m, m2);
30 | assert_eq!(m, m3);
31 | assert_eq!(m, m4);
32 | assert_eq!(m, m5);
33 | assert_eq!(m, m6);
34 |
35 | // All the following matrices are equal but constructed in different ways.
36 | // This time, we used a dynamically-sized matrix to show the extra arguments
37 | // for the matrix shape.
38 | let dm = DMatrix::from_row_slice(
39 | 4,
40 | 3,
41 | &[1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0],
42 | );
43 |
44 | let dm1 = DMatrix::from_diagonal_element(4, 3, 1.0);
45 | let dm2 = DMatrix::identity(4, 3);
46 | let dm3 = DMatrix::from_fn(4, 3, |r, c| if r == c { 1.0 } else { 0.0 });
47 | let dm4 = DMatrix::from_iterator(
48 | 4,
49 | 3,
50 | [
51 | // Components listed column-by-column.
52 | 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0,
53 | ]
54 | .iter()
55 | .cloned(),
56 | );
57 |
58 | assert_eq!(dm, dm1);
59 | assert_eq!(dm, dm2);
60 | assert_eq!(dm, dm3);
61 | assert_eq!(dm, dm4);
62 | }
63 |
--------------------------------------------------------------------------------
/examples/mvp.rs:
--------------------------------------------------------------------------------
1 | #![allow(unused_variables)]
2 |
3 | extern crate nalgebra as na;
4 |
5 | use na::{Isometry3, Perspective3, Point3, Vector3};
6 | use std::f32::consts;
7 |
8 | fn main() {
9 | // Our object is translated along the x axis.
10 | let model = Isometry3::new(Vector3::x(), na::zero());
11 |
12 | // Our camera looks toward the point (1.0, 0.0, 0.0).
13 | // It is located at (0.0, 0.0, 1.0).
14 | let eye = Point3::new(0.0, 0.0, 1.0);
15 | let target = Point3::new(1.0, 0.0, 0.0);
16 | let view = Isometry3::look_at_rh(&eye, &target, &Vector3::y());
17 |
18 | // A perspective projection.
19 | let projection = Perspective3::new(16.0 / 9.0, consts::PI / 2.0, 1.0, 1000.0);
20 |
21 | // The combination of the model with the view is still an isometry.
22 | let model_view = view * model;
23 |
24 | // Convert everything to a `Matrix4` so that they can be combined.
25 | let mat_model_view = model_view.to_homogeneous();
26 |
27 | // Combine everything.
28 | let model_view_projection = projection.as_matrix() * mat_model_view;
29 | }
30 |
--------------------------------------------------------------------------------
/examples/point_construction.rs:
--------------------------------------------------------------------------------
1 | extern crate nalgebra as na;
2 |
3 | use na::{Point3, Vector3, Vector4};
4 |
5 | fn main() {
6 | // Build using components directly.
7 | let p0 = Point3::new(2.0, 3.0, 4.0);
8 |
9 | // Build from a coordinates vector.
10 | let coords = Vector3::new(2.0, 3.0, 4.0);
11 | let p1 = Point3::from(coords);
12 |
13 | // Build by translating the origin.
14 | let translation = Vector3::new(2.0, 3.0, 4.0);
15 | let p2 = Point3::origin() + translation;
16 |
17 | // Build from homogeneous coordinates. The last component of the
18 | // vector will be removed and all other components divided by 10.0.
19 | let homogeneous_coords = Vector4::new(20.0, 30.0, 40.0, 10.0);
20 | let p3 = Point3::from_homogeneous(homogeneous_coords);
21 |
22 | assert_eq!(p0, p1);
23 | assert_eq!(p0, p2);
24 | assert_eq!(p0, p3.unwrap());
25 | }
26 |
--------------------------------------------------------------------------------
/examples/raw_pointer.rs:
--------------------------------------------------------------------------------
1 | extern crate nalgebra as na;
2 |
3 | use na::{Matrix3, Point3, Vector3};
4 |
5 | fn main() {
6 | let v = Vector3::new(1.0f32, 0.0, 1.0);
7 | let p = Point3::new(1.0f32, 0.0, 1.0);
8 | let m = na::one::>();
9 |
10 | // Convert to arrays.
11 | let v_array = v.as_slice();
12 | let p_array = p.coords.as_slice();
13 | let m_array = m.as_slice();
14 |
15 | // Get data pointers.
16 | let v_pointer = v_array.as_ptr();
17 | let p_pointer = p_array.as_ptr();
18 | let m_pointer = m_array.as_ptr();
19 |
20 | /* Then pass the raw pointers to some graphics API. */
21 |
22 | #[allow(clippy::float_cmp)]
23 | unsafe {
24 | assert_eq!(*v_pointer, 1.0);
25 | assert_eq!(*v_pointer.offset(1), 0.0);
26 | assert_eq!(*v_pointer.offset(2), 1.0);
27 |
28 | assert_eq!(*p_pointer, 1.0);
29 | assert_eq!(*p_pointer.offset(1), 0.0);
30 | assert_eq!(*p_pointer.offset(2), 1.0);
31 |
32 | assert_eq!(*m_pointer, 1.0);
33 | assert_eq!(*m_pointer.offset(4), 1.0);
34 | assert_eq!(*m_pointer.offset(8), 1.0);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/examples/reshaping.rs:
--------------------------------------------------------------------------------
1 | #![cfg_attr(rustfmt, rustfmt_skip)]
2 |
3 | extern crate nalgebra as na;
4 |
5 | use na::{DMatrix, Dyn, Matrix2x3, Matrix3x2, Const};
6 |
7 | fn main() {
8 | // Matrices can be reshaped in-place without moving or copying values.
9 | let m1 = Matrix2x3::new(
10 | 1.1, 1.2, 1.3,
11 | 2.1, 2.2, 2.3
12 | );
13 | let m2 = Matrix3x2::new(
14 | 1.1, 2.2,
15 | 2.1, 1.3,
16 | 1.2, 2.3
17 | );
18 |
19 | let m3 = m1.reshape_generic(Const::<3>, Const::<2>);
20 | assert_eq!(m3, m2);
21 |
22 | // Note that, for statically sized matrices, invalid reshapes will not compile:
23 | //let m4 = m3.reshape_generic(U3, U3);
24 |
25 | // If dynamically sized matrices are used, the reshaping is checked at run-time.
26 | let dm1 = DMatrix::from_row_slice(
27 | 4,
28 | 3,
29 | &[
30 | 1.0, 0.0, 0.0,
31 | 0.0, 0.0, 1.0,
32 | 0.0, 0.0, 0.0,
33 | 0.0, 1.0, 0.0
34 | ],
35 | );
36 | let dm2 = DMatrix::from_row_slice(
37 | 6,
38 | 2,
39 | &[
40 | 1.0, 0.0,
41 | 0.0, 1.0,
42 | 0.0, 0.0,
43 | 0.0, 1.0,
44 | 0.0, 0.0,
45 | 0.0, 0.0,
46 | ],
47 | );
48 |
49 | let dm3 = dm1.reshape_generic(Dyn(6), Dyn(2));
50 | assert_eq!(dm3, dm2);
51 |
52 | // Invalid reshapings of dynamic matrices will panic at run-time.
53 | //let dm4 = dm3.reshape_generic(Dyn(6), Dyn(6));
54 | }
55 |
--------------------------------------------------------------------------------
/examples/scalar_genericity.rs:
--------------------------------------------------------------------------------
1 | extern crate nalgebra as na;
2 |
3 | use na::{Scalar, Vector3};
4 | use simba::scalar::RealField;
5 |
6 | fn print_vector(m: &Vector3) {
7 | println!("{:?}", m)
8 | }
9 |
10 | fn print_norm(v: &Vector3) {
11 | // NOTE: alternatively, nalgebra already defines `v.norm()`.
12 | let norm = v.dot(v).sqrt();
13 |
14 | // The RealField bound implies that T is Display so we can
15 | // use "{}" instead of "{:?}" for the format string.
16 | println!("{}", norm)
17 | }
18 |
19 | fn main() {
20 | let v1 = Vector3::new(1, 2, 3);
21 | let v2 = Vector3::new(1.0, 2.0, 3.0);
22 |
23 | print_vector(&v1);
24 | print_norm(&v2);
25 | }
26 |
--------------------------------------------------------------------------------
/examples/screen_to_view_coords.rs:
--------------------------------------------------------------------------------
1 | #![allow(unused_variables)]
2 |
3 | extern crate nalgebra as na;
4 |
5 | use na::{Perspective3, Point2, Point3, Unit};
6 | use std::f32::consts;
7 |
8 | fn main() {
9 | let projection = Perspective3::new(800.0 / 600.0, consts::PI / 2.0, 1.0, 1000.0);
10 | let screen_point = Point2::new(10.0f32, 20.0);
11 |
12 | // Compute two points in clip-space.
13 | // "ndc" = normalized device coordinates.
14 | let near_ndc_point = Point3::new(screen_point.x / 800.0, screen_point.y / 600.0, -1.0);
15 | let far_ndc_point = Point3::new(screen_point.x / 800.0, screen_point.y / 600.0, 1.0);
16 |
17 | // Unproject them to view-space.
18 | let near_view_point = projection.unproject_point(&near_ndc_point);
19 | let far_view_point = projection.unproject_point(&far_ndc_point);
20 |
21 | // Compute the view-space line parameters.
22 | let line_location = near_view_point;
23 | let line_direction = Unit::new_normalize(far_view_point - near_view_point);
24 | }
25 |
--------------------------------------------------------------------------------
/examples/transform_conversion.rs:
--------------------------------------------------------------------------------
1 | extern crate nalgebra as na;
2 |
3 | use na::{Isometry2, Similarity2, Vector2};
4 | use std::f32::consts;
5 |
6 | fn main() {
7 | // Isometry -> Similarity conversion always succeeds.
8 | let iso = Isometry2::new(Vector2::new(1.0f32, 2.0), na::zero());
9 | let _: Similarity2 = na::convert(iso);
10 |
11 | // Similarity -> Isometry conversion fails if the scaling factor is not 1.0.
12 | let sim_without_scaling = Similarity2::new(Vector2::new(1.0f32, 2.0), consts::PI, 1.0);
13 | let sim_with_scaling = Similarity2::new(Vector2::new(1.0f32, 2.0), consts::PI, 2.0);
14 |
15 | let iso_success: Option> = na::try_convert(sim_without_scaling);
16 | let iso_fail: Option> = na::try_convert(sim_with_scaling);
17 |
18 | assert!(iso_success.is_some());
19 | assert!(iso_fail.is_none());
20 |
21 | // Similarity -> Isometry conversion can be forced at your own risks.
22 | let iso_forced: Isometry2 = na::convert_unchecked(sim_with_scaling);
23 | assert_eq!(iso_success.unwrap(), iso_forced);
24 | }
25 |
--------------------------------------------------------------------------------
/examples/transform_matrix4.rs:
--------------------------------------------------------------------------------
1 | #[macro_use]
2 | extern crate approx;
3 | extern crate nalgebra as na;
4 |
5 | use na::{Matrix4, Point3, Vector3};
6 | use std::f32::consts;
7 |
8 | fn main() {
9 | // Create a uniform scaling matrix with scaling factor 2.
10 | let mut m = Matrix4::new_scaling(2.0);
11 |
12 | assert_eq!(m.transform_vector(&Vector3::x()), Vector3::x() * 2.0);
13 | assert_eq!(m.transform_vector(&Vector3::y()), Vector3::y() * 2.0);
14 | assert_eq!(m.transform_vector(&Vector3::z()), Vector3::z() * 2.0);
15 |
16 | // Append a nonuniform scaling in-place.
17 | m.append_nonuniform_scaling_mut(&Vector3::new(1.0, 2.0, 3.0));
18 |
19 | assert_eq!(m.transform_vector(&Vector3::x()), Vector3::x() * 2.0);
20 | assert_eq!(m.transform_vector(&Vector3::y()), Vector3::y() * 4.0);
21 | assert_eq!(m.transform_vector(&Vector3::z()), Vector3::z() * 6.0);
22 |
23 | // Append a translation out-of-place.
24 | let m2 = m.append_translation(&Vector3::new(42.0, 0.0, 0.0));
25 |
26 | assert_eq!(
27 | m2.transform_point(&Point3::new(1.0, 1.0, 1.0)),
28 | Point3::new(42.0 + 2.0, 4.0, 6.0)
29 | );
30 |
31 | // Create rotation.
32 | let rot = Matrix4::from_scaled_axis(Vector3::x() * consts::PI);
33 | let rot_then_m = m * rot; // Right-multiplication is equivalent to prepending `rot` to `m`.
34 | let m_then_rot = rot * m; // Left-multiplication is equivalent to appending `rot` to `m`.
35 |
36 | let pt = Point3::new(1.0, 2.0, 3.0);
37 |
38 | assert_relative_eq!(
39 | m.transform_point(&rot.transform_point(&pt)),
40 | rot_then_m.transform_point(&pt)
41 | );
42 | assert_relative_eq!(
43 | rot.transform_point(&m.transform_point(&pt)),
44 | m_then_rot.transform_point(&pt)
45 | );
46 | }
47 |
--------------------------------------------------------------------------------
/examples/transform_vector_point.rs:
--------------------------------------------------------------------------------
1 | #[macro_use]
2 | extern crate approx;
3 | extern crate nalgebra as na;
4 |
5 | use na::{Isometry2, Point2, Vector2};
6 | use std::f32;
7 |
8 | fn main() {
9 | let t = Isometry2::new(Vector2::new(1.0, 1.0), f32::consts::PI);
10 | let p = Point2::new(1.0, 0.0); // Will be affected by te rotation and the translation.
11 | let v = Vector2::x(); // Will *not* be affected by the translation.
12 |
13 | assert_relative_eq!(t * p, Point2::new(-1.0 + 1.0, 1.0));
14 | // ^^^^ │ ^^^^^^^^
15 | // rotated │ translated
16 |
17 | assert_relative_eq!(t * v, Vector2::new(-1.0, 0.0));
18 | // ^^^^^
19 | // rotated only
20 | }
21 |
--------------------------------------------------------------------------------
/examples/transform_vector_point3.rs:
--------------------------------------------------------------------------------
1 | extern crate nalgebra as na;
2 |
3 | use na::{Matrix4, Point3, Vector3, Vector4};
4 |
5 | fn main() {
6 | let mut m = Matrix4::new_rotation_wrt_point(Vector3::x() * 1.57, Point3::new(1.0, 2.0, 1.0));
7 | m.append_scaling_mut(2.0);
8 |
9 | let point1 = Point3::new(2.0, 3.0, 4.0);
10 | let homogeneous_point2 = Vector4::new(2.0, 3.0, 4.0, 1.0);
11 |
12 | // First option: use the dedicated `.transform_point(...)` method.
13 | let transformed_point1 = m.transform_point(&point1);
14 | // Second option: use the homogeneous coordinates of the point.
15 | let transformed_homogeneous_point2 = m * homogeneous_point2;
16 |
17 | // Recover the 3D point from its 4D homogeneous coordinates.
18 | let transformed_point2 = Point3::from_homogeneous(transformed_homogeneous_point2);
19 |
20 | // Check that transforming the 3D point with the `.transform_point` method is
21 | // indeed equivalent to multiplying its 4D homogeneous coordinates by the 4x4
22 | // matrix.
23 | assert_eq!(transformed_point1, transformed_point2.unwrap());
24 | }
25 |
--------------------------------------------------------------------------------
/examples/transformation_pointer.rs:
--------------------------------------------------------------------------------
1 | extern crate nalgebra as na;
2 |
3 | use na::{Isometry3, Vector3};
4 |
5 | fn main() {
6 | let iso = Isometry3::new(Vector3::new(1.0f32, 0.0, 1.0), na::zero());
7 |
8 | // Compute the homogeneous coordinates first.
9 | let iso_matrix = iso.to_homogeneous();
10 | let iso_array = iso_matrix.as_slice();
11 | let iso_pointer = iso_array.as_ptr();
12 |
13 | /* Then pass the raw pointer to some graphics API. */
14 |
15 | #[allow(clippy::float_cmp)]
16 | unsafe {
17 | assert_eq!(*iso_pointer, 1.0);
18 | assert_eq!(*iso_pointer.offset(5), 1.0);
19 | assert_eq!(*iso_pointer.offset(10), 1.0);
20 | assert_eq!(*iso_pointer.offset(15), 1.0);
21 |
22 | assert_eq!(*iso_pointer.offset(12), 1.0);
23 | assert_eq!(*iso_pointer.offset(13), 0.0);
24 | assert_eq!(*iso_pointer.offset(14), 1.0);
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/examples/unit_wrapper.rs:
--------------------------------------------------------------------------------
1 | #![allow(clippy::float_cmp)]
2 | extern crate nalgebra as na;
3 |
4 | use na::{Unit, Vector3};
5 |
6 | fn length_on_direction_with_unit(v: &Vector3, dir: &Unit>) -> f32 {
7 | // No need to normalize `dir`: we know that it is non-zero and normalized.
8 | v.dot(dir.as_ref())
9 | }
10 |
11 | fn length_on_direction_without_unit(v: &Vector3, dir: &Vector3) -> f32 {
12 | // Obligatory normalization of the direction vector (and test, for robustness).
13 | if let Some(unit_dir) = dir.try_normalize(1.0e-6) {
14 | v.dot(&unit_dir)
15 | } else {
16 | // Normalization failed because the norm was too small.
17 | panic!("Invalid input direction.")
18 | }
19 | }
20 |
21 | fn main() {
22 | let v = Vector3::new(1.0, 2.0, 3.0);
23 |
24 | let l1 = length_on_direction_with_unit(&v, &Vector3::y_axis());
25 | let l2 = length_on_direction_without_unit(&v, &Vector3::y());
26 |
27 | assert_eq!(l1, l2)
28 | }
29 |
--------------------------------------------------------------------------------
/nalgebra-glm/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "nalgebra-glm"
3 | version = "0.19.0"
4 | authors = ["sebcrozet "]
5 |
6 | description = "A computer-graphics oriented API for nalgebra, inspired by the C++ GLM library."
7 | documentation = "https://www.nalgebra.org/docs"
8 | homepage = "https://nalgebra.org"
9 | repository = "https://github.com/dimforge/nalgebra"
10 | readme = "../README.md"
11 | categories = ["science", "mathematics", "wasm", "no standard library"]
12 | keywords = ["linear", "algebra", "matrix", "vector", "math"]
13 | license = "Apache-2.0"
14 | edition = "2018"
15 |
16 | [badges]
17 | maintenance = { status = "actively-developed" }
18 |
19 | [features]
20 | default = ["std"]
21 | std = ["nalgebra/std", "simba/std"]
22 | arbitrary = ["nalgebra/arbitrary"]
23 | serde-serialize = ["nalgebra/serde-serialize-no-std"]
24 |
25 | # Conversion
26 | convert-mint = ["nalgebra/mint"]
27 | convert-bytemuck = ["nalgebra/bytemuck"]
28 | convert-glam014 = ["nalgebra/glam014"]
29 | convert-glam015 = ["nalgebra/glam015"]
30 | convert-glam016 = ["nalgebra/glam016"]
31 | convert-glam017 = ["nalgebra/glam017"]
32 | convert-glam018 = ["nalgebra/glam018"]
33 |
34 | [dependencies]
35 | num-traits = { version = "0.2", default-features = false }
36 | approx = { version = "0.5", default-features = false }
37 | simba = { version = "0.9", default-features = false }
38 | nalgebra = { path = "..", version = "0.33", default-features = false }
39 |
--------------------------------------------------------------------------------
/nalgebra-glm/LICENSE:
--------------------------------------------------------------------------------
1 | ../LICENSE
--------------------------------------------------------------------------------
/nalgebra-glm/src/exponential.rs:
--------------------------------------------------------------------------------
1 | use crate::aliases::TVec;
2 | use crate::RealNumber;
3 |
4 | /// Component-wise exponential.
5 | ///
6 | /// # See also:
7 | ///
8 | /// * [`exp2()`]
9 | pub fn exp(v: &TVec) -> TVec {
10 | v.map(|x| x.exp())
11 | }
12 |
13 | /// Component-wise base-2 exponential.
14 | ///
15 | /// # See also:
16 | ///
17 | /// * [`exp()`]
18 | pub fn exp2(v: &TVec) -> TVec {
19 | v.map(|x| x.exp2())
20 | }
21 |
22 | /// Compute the inverse of the square root of each component of `v`.
23 | ///
24 | /// # See also:
25 | ///
26 | /// * [`sqrt()`]
27 | pub fn inversesqrt(v: &TVec) -> TVec {
28 | v.map(|x| T::one() / x.sqrt())
29 | }
30 |
31 | /// Component-wise logarithm.
32 | ///
33 | /// # See also:
34 | ///
35 | /// * [`log2()`]
36 | pub fn log(v: &TVec) -> TVec {
37 | v.map(|x| x.ln())
38 | }
39 |
40 | /// Component-wise base-2 logarithm.
41 | ///
42 | /// # See also:
43 | ///
44 | /// * [`log()`]
45 | pub fn log2(v: &TVec) -> TVec {
46 | v.map(|x| x.log2())
47 | }
48 |
49 | /// Component-wise power.
50 | pub fn pow(base: &TVec, exponent: &TVec) -> TVec {
51 | base.zip_map(exponent, |b, e| b.powf(e))
52 | }
53 |
54 | /// Component-wise square root.
55 | ///
56 | /// # See also:
57 | ///
58 | /// * [`exp()`]
59 | /// * [`exp2()`]
60 | /// * [`inversesqrt()`]
61 | /// * [`pow`]
62 | pub fn sqrt(v: &TVec) -> TVec {
63 | v.map(|x| x.sqrt())
64 | }
65 |
--------------------------------------------------------------------------------
/nalgebra-glm/src/ext/quaternion_common.rs:
--------------------------------------------------------------------------------
1 | use na::Unit;
2 |
3 | use crate::aliases::Qua;
4 | use crate::RealNumber;
5 |
6 | /// The conjugate of `q`.
7 | pub fn quat_conjugate(q: &Qua) -> Qua {
8 | q.conjugate()
9 | }
10 |
11 | /// The inverse of `q`.
12 | pub fn quat_inverse(q: &Qua) -> Qua {
13 | q.try_inverse().unwrap_or_else(na::zero)
14 | }
15 |
16 | //pub fn quat_isinf(x: &Qua) -> TVec {
17 | // x.coords.map(|e| e.is_inf())
18 | //}
19 |
20 | //pub fn quat_isnan(x: &Qua) -> TVec {
21 | // x.coords.map(|e| e.is_nan())
22 | //}
23 |
24 | /// Interpolate linearly between `x` and `y`.
25 | pub fn quat_lerp(x: &Qua, y: &Qua, a: T) -> Qua {
26 | x.lerp(y, a)
27 | }
28 |
29 | //pub fn quat_mix(x: &Qua, y: &Qua, a: T) -> Qua {
30 | // x * (T::one() - a) + y * a
31 | //}
32 |
33 | /// Interpolate spherically between `x` and `y`.
34 | pub fn quat_slerp(x: &Qua, y: &Qua, a: T) -> Qua {
35 | Unit::new_normalize(*x)
36 | .slerp(&Unit::new_normalize(*y), a)
37 | .into_inner()
38 | }
39 |
--------------------------------------------------------------------------------
/nalgebra-glm/src/ext/quaternion_geometric.rs:
--------------------------------------------------------------------------------
1 | use crate::RealNumber;
2 |
3 | use crate::aliases::Qua;
4 |
5 | /// Multiplies two quaternions.
6 | pub fn quat_cross(q1: &Qua, q2: &Qua) -> Qua {
7 | q1 * q2
8 | }
9 |
10 | /// The scalar product of two quaternions.
11 | pub fn quat_dot(x: &Qua, y: &Qua) -> T {
12 | x.dot(y)
13 | }
14 |
15 | /// The magnitude of the quaternion `q`.
16 | pub fn quat_length(q: &Qua) -> T {
17 | q.norm()
18 | }
19 |
20 | /// The magnitude of the quaternion `q`.
21 | pub fn quat_magnitude(q: &Qua) -> T {
22 | q.norm()
23 | }
24 |
25 | /// Normalizes the quaternion `q`.
26 | pub fn quat_normalize(q: &Qua) -> Qua {
27 | q.normalize()
28 | }
29 |
--------------------------------------------------------------------------------
/nalgebra-glm/src/ext/quaternion_relational.rs:
--------------------------------------------------------------------------------
1 | use crate::aliases::{Qua, TVec};
2 | use crate::RealNumber;
3 |
4 | /// Component-wise equality comparison between two quaternions.
5 | pub fn quat_equal(x: &Qua, y: &Qua) -> TVec {
6 | crate::equal(&x.coords, &y.coords)
7 | }
8 |
9 | /// Component-wise approximate equality comparison between two quaternions.
10 | pub fn quat_equal_eps(x: &Qua, y: &Qua, epsilon: T) -> TVec {
11 | crate::equal_eps(&x.coords, &y.coords, epsilon)
12 | }
13 |
14 | /// Component-wise non-equality comparison between two quaternions.
15 | pub fn quat_not_equal(x: &Qua, y: &Qua) -> TVec {
16 | crate::not_equal(&x.coords, &y.coords)
17 | }
18 |
19 | /// Component-wise approximate non-equality comparison between two quaternions.
20 | pub fn quat_not_equal_eps(x: &Qua, y: &Qua, epsilon: T) -> TVec {
21 | crate::not_equal_eps(&x.coords, &y.coords, epsilon)
22 | }
23 |
--------------------------------------------------------------------------------
/nalgebra-glm/src/ext/quaternion_transform.rs:
--------------------------------------------------------------------------------
1 | use na::{Unit, UnitQuaternion};
2 |
3 | use crate::aliases::{Qua, TVec3};
4 | use crate::RealNumber;
5 |
6 | /// Computes the quaternion exponential.
7 | pub fn quat_exp(q: &Qua) -> Qua {
8 | q.exp()
9 | }
10 |
11 | /// Computes the quaternion logarithm.
12 | pub fn quat_log(q: &Qua) -> Qua {
13 | q.ln()
14 | }
15 |
16 | /// Raises the quaternion `q` to the power `y`.
17 | pub fn quat_pow(q: &Qua, y: T) -> Qua {
18 | q.powf(y)
19 | }
20 |
21 | /// Builds a quaternion from an axis and an angle, and right-multiply it to the quaternion `q`.
22 | pub fn quat_rotate(q: &Qua, angle: T, axis: &TVec3) -> Qua {
23 | q * UnitQuaternion::from_axis_angle(&Unit::new_normalize(*axis), angle).into_inner()
24 | }
25 |
26 | //pub fn quat_sqrt(q: &Qua) -> Qua {
27 | // unimplemented!()
28 | //}
29 |
--------------------------------------------------------------------------------
/nalgebra-glm/src/ext/quaternion_trigonometric.rs:
--------------------------------------------------------------------------------
1 | use na::{Unit, UnitQuaternion};
2 |
3 | use crate::aliases::{Qua, TVec3};
4 | use crate::RealNumber;
5 |
6 | /// The rotation angle of this quaternion assumed to be normalized.
7 | pub fn quat_angle(x: &Qua) -> T {
8 | UnitQuaternion::from_quaternion(*x).angle()
9 | }
10 |
11 | /// Creates a quaternion from an axis and an angle.
12 | pub fn quat_angle_axis(angle: T, axis: &TVec3) -> Qua {
13 | UnitQuaternion::from_axis_angle(&Unit::new_normalize(*axis), angle).into_inner()
14 | }
15 |
16 | /// The rotation axis of a quaternion assumed to be normalized.
17 | pub fn quat_axis(x: &Qua) -> TVec3 {
18 | if let Some(a) = UnitQuaternion::from_quaternion(*x).axis() {
19 | a.into_inner()
20 | } else {
21 | TVec3::zeros()
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/nalgebra-glm/src/ext/scalar_constants.rs:
--------------------------------------------------------------------------------
1 | use crate::RealNumber;
2 | use approx::AbsDiffEq;
3 |
4 | /// Default epsilon value used for approximate comparison.
5 | pub fn epsilon>() -> T {
6 | T::default_epsilon()
7 | }
8 |
9 | /// The value of PI.
10 | ///
11 | /// # See also:
12 | ///
13 | /// * [`four_over_pi()`](crate::four_over_pi)
14 | /// * [`half_pi()`](crate::half_pi)
15 | /// * [`one_over_pi()`](crate::one_over_pi)
16 | /// * [`one_over_two_pi()`](crate::one_over_two_pi)
17 | /// * [`quarter_pi()`](crate::quarter_pi)
18 | /// * [`root_half_pi()`](crate::root_half_pi)
19 | /// * [`root_pi()`](crate::root_pi)
20 | /// * [`root_two_pi()`](crate::root_two_pi)
21 | /// * [`three_over_two_pi()`](crate::three_over_two_pi)
22 | /// * [`two_over_pi()`](crate::two_over_pi)
23 | /// * [`two_over_root_pi()`](crate::two_over_root_pi)
24 | /// * [`two_pi()`](crate::two_pi)
25 | pub fn pi() -> T {
26 | T::pi()
27 | }
28 |
--------------------------------------------------------------------------------
/nalgebra-glm/src/ext/vector_relational.rs:
--------------------------------------------------------------------------------
1 | use crate::aliases::TVec;
2 | use crate::traits::Number;
3 |
4 | /// Component-wise approximate equality of two vectors, using a scalar epsilon.
5 | ///
6 | /// # See also:
7 | ///
8 | /// * [`equal_eps_vec()`]
9 | /// * [`not_equal_eps()`]
10 | /// * [`not_equal_eps_vec()`]
11 | pub fn equal_eps(
12 | x: &TVec,
13 | y: &TVec,
14 | epsilon: T,
15 | ) -> TVec {
16 | x.zip_map(y, |x, y| abs_diff_eq!(x, y, epsilon = epsilon))
17 | }
18 |
19 | /// Component-wise approximate equality of two vectors, using a per-component epsilon.
20 | ///
21 | /// # See also:
22 | ///
23 | /// * [`equal_eps()`]
24 | /// * [`not_equal_eps()`]
25 | /// * [`not_equal_eps_vec()`]
26 | pub fn equal_eps_vec(
27 | x: &TVec,
28 | y: &TVec,
29 | epsilon: &TVec,
30 | ) -> TVec {
31 | x.zip_zip_map(y, epsilon, |x, y, eps| abs_diff_eq!(x, y, epsilon = eps))
32 | }
33 |
34 | /// Component-wise approximate non-equality of two vectors, using a scalar epsilon.
35 | ///
36 | /// # See also:
37 | ///
38 | /// * [`equal_eps()`]
39 | /// * [`equal_eps_vec()`]
40 | /// * [`not_equal_eps_vec()`]
41 | pub fn not_equal_eps(
42 | x: &TVec,
43 | y: &TVec,
44 | epsilon: T,
45 | ) -> TVec {
46 | x.zip_map(y, |x, y| abs_diff_ne!(x, y, epsilon = epsilon))
47 | }
48 |
49 | /// Component-wise approximate non-equality of two vectors, using a per-component epsilon.
50 | ///
51 | /// # See also:
52 | ///
53 | /// * [`equal_eps()`]
54 | /// * [`equal_eps_vec()`]
55 | /// * [`not_equal_eps()`]
56 | pub fn not_equal_eps_vec(
57 | x: &TVec,
58 | y: &TVec,
59 | epsilon: &TVec,
60 | ) -> TVec {
61 | x.zip_zip_map(y, epsilon, |x, y, eps| abs_diff_ne!(x, y, epsilon = eps))
62 | }
63 |
--------------------------------------------------------------------------------
/nalgebra-glm/src/gtc/epsilon.rs:
--------------------------------------------------------------------------------
1 | // NOTE those are actually duplicates of vector_relational.rs
2 |
3 | /*
4 | use approx::AbsDiffEq;
5 | use na::DefaultAllocator;
6 |
7 | use crate::traits::{Alloc, Number, Dimension};
8 | use crate::aliases::TVec;
9 |
10 | /// Component-wise approximate equality between two vectors.
11 | pub fn epsilon_equal(x: &TVec, y: &TVec, epsilon: T) -> TVec
12 | where DefaultAllocator: Alloc {
13 | x.zip_map(y, |x, y| abs_diff_eq!(x, y, epsilon = epsilon))
14 | }
15 |
16 | /// Component-wise approximate equality between two scalars.
17 | pub fn epsilon_equal2>(x: T, y: T, epsilon: T) -> bool {
18 | abs_diff_eq!(x, y, epsilon = epsilon)
19 | }
20 |
21 | /// Component-wise approximate non-equality between two vectors.
22 | pub fn epsilon_not_equal(x: &TVec, y: &TVec, epsilon: T) -> TVec
23 | where DefaultAllocator: Alloc {
24 | x.zip_map(y, |x, y| abs_diff_ne!(x, y, epsilon = epsilon))
25 | }
26 |
27 | /// Component-wise approximate non-equality between two scalars.
28 | pub fn epsilon_not_equal2>(x: T, y: T, epsilon: T) -> bool {
29 | abs_diff_ne!(x, y, epsilon = epsilon)
30 | }
31 | */
32 |
--------------------------------------------------------------------------------
/nalgebra-glm/src/gtc/integer.rs:
--------------------------------------------------------------------------------
1 | //use na::Scalar;
2 | //
3 | //
4 | //use crate::aliases::TVec;
5 |
6 | //pub fn iround(x: &TVec) -> TVec {
7 | // x.map(|x| x.round())
8 | //}
9 | //
10 | //pub fn log2(x: I) -> I {
11 | // unimplemented!()
12 | //}
13 | //
14 | //pub fn uround(x: &TVec) -> TVec {
15 | // unimplemented!()
16 | //}
17 |
--------------------------------------------------------------------------------
/nalgebra-glm/src/gtc/matrix_access.rs:
--------------------------------------------------------------------------------
1 | use na::Scalar;
2 |
3 | use crate::aliases::{TMat, TVec};
4 |
5 | /// The `index`-th column of the matrix `m`.
6 | ///
7 | /// # See also:
8 | ///
9 | /// * [`row()`]
10 | /// * [`set_column()`]
11 | /// * [`set_row()`]
12 | pub fn column(
13 | m: &TMat,
14 | index: usize,
15 | ) -> TVec {
16 | m.column(index).into_owned()
17 | }
18 |
19 | /// Sets to `x` the `index`-th column of the matrix `m`.
20 | ///
21 | /// # See also:
22 | ///
23 | /// * [`column()`]
24 | /// * [`row()`]
25 | /// * [`set_row()`]
26 | pub fn set_column(
27 | m: &TMat,
28 | index: usize,
29 | x: &TVec,
30 | ) -> TMat {
31 | let mut res = m.clone();
32 | res.set_column(index, x);
33 | res
34 | }
35 |
36 | /// The `index`-th row of the matrix `m`.
37 | ///
38 | /// # See also:
39 | ///
40 | /// * [`column()`]
41 | /// * [`set_column()`]
42 | /// * [`set_row()`]
43 | pub fn row(
44 | m: &TMat,
45 | index: usize,
46 | ) -> TVec {
47 | m.row(index).into_owned().transpose()
48 | }
49 |
50 | /// Sets to `x` the `index`-th row of the matrix `m`.
51 | ///
52 | /// # See also:
53 | ///
54 | /// * [`column()`]
55 | /// * [`row()`]
56 | /// * [`set_column()`]
57 | pub fn set_row(
58 | m: &TMat,
59 | index: usize,
60 | x: &TVec,
61 | ) -> TMat {
62 | let mut res = m.clone();
63 | res.set_row(index, &x.transpose());
64 | res
65 | }
66 |
--------------------------------------------------------------------------------
/nalgebra-glm/src/gtc/matrix_inverse.rs:
--------------------------------------------------------------------------------
1 | use crate::RealNumber;
2 |
3 | use crate::aliases::TMat;
4 |
5 | /// Fast matrix inverse for affine matrix.
6 | pub fn affine_inverse(m: TMat) -> TMat {
7 | // TODO: this should be optimized.
8 | m.try_inverse().unwrap_or_else(TMat::<_, D, D>::zeros)
9 | }
10 |
11 | /// Compute the transpose of the inverse of a matrix.
12 | pub fn inverse_transpose(m: TMat) -> TMat {
13 | m.try_inverse()
14 | .unwrap_or_else(TMat::<_, D, D>::zeros)
15 | .transpose()
16 | }
17 |
--------------------------------------------------------------------------------
/nalgebra-glm/src/gtc/mod.rs:
--------------------------------------------------------------------------------
1 | //! (Reexported) Recommended features not specified by GLSL specification
2 |
3 | //pub use self::bitfield::*;
4 | pub use self::constants::{
5 | e, euler, four_over_pi, golden_ratio, half_pi, ln_ln_two, ln_ten, ln_two, one, one_over_pi,
6 | one_over_root_two, one_over_two_pi, quarter_pi, root_five, root_half_pi, root_ln_four, root_pi,
7 | root_three, root_two, root_two_pi, third, three_over_two_pi, two_over_pi, two_over_root_pi,
8 | two_pi, two_thirds, zero,
9 | };
10 | //pub use self::integer::*;
11 | pub use self::matrix_access::{column, row, set_column, set_row};
12 | pub use self::matrix_inverse::{affine_inverse, inverse_transpose};
13 | //pub use self::packing::*;
14 | //pub use self::reciprocal::*;
15 | //pub use self::round::*;
16 | pub use self::type_ptr::{
17 | make_mat2, make_mat2x2, make_mat2x3, make_mat2x4, make_mat3, make_mat3x2, make_mat3x3,
18 | make_mat3x4, make_mat4, make_mat4x2, make_mat4x3, make_mat4x4, make_quat, make_vec1, make_vec2,
19 | make_vec3, make_vec4, mat2_to_mat3, mat2_to_mat4, mat3_to_mat2, mat3_to_mat4, mat4_to_mat2,
20 | mat4_to_mat3, value_ptr, value_ptr_mut, vec1_to_vec2, vec1_to_vec3, vec1_to_vec4, vec2_to_vec1,
21 | vec2_to_vec2, vec2_to_vec3, vec2_to_vec4, vec3_to_vec1, vec3_to_vec2, vec3_to_vec3,
22 | vec3_to_vec4, vec4_to_vec1, vec4_to_vec2, vec4_to_vec3, vec4_to_vec4,
23 | };
24 | //pub use self::ulp::*;
25 | pub use self::quaternion::{
26 | quat_cast, quat_euler_angles, quat_greater_than, quat_greater_than_equal, quat_less_than,
27 | quat_less_than_equal, quat_look_at, quat_look_at_lh, quat_look_at_rh, quat_pitch, quat_roll,
28 | quat_yaw,
29 | };
30 |
31 | //mod bitfield;
32 | mod constants;
33 | mod epsilon;
34 | //mod integer;
35 | mod matrix_access;
36 | mod matrix_inverse;
37 | //mod packing;
38 | //mod reciprocal;
39 | //mod round;
40 | mod type_ptr;
41 | //mod ulp;
42 | mod quaternion;
43 |
--------------------------------------------------------------------------------
/nalgebra-glm/src/gtc/reciprocal.rs:
--------------------------------------------------------------------------------
1 | pub fn acot(x: T) -> T {
2 | unimplemented!()
3 | }
4 |
5 | pub fn acoth(x: T) -> T {
6 | unimplemented!()
7 | }
8 |
9 | pub fn acsc(x: T) -> T {
10 | unimplemented!()
11 | }
12 |
13 | pub fn acsch(x: T) -> T {
14 | unimplemented!()
15 | }
16 |
17 | pub fn asec(x: T) -> T {
18 | unimplemented!()
19 | }
20 |
21 | pub fn asech(x: T) -> T {
22 | unimplemented!()
23 | }
24 |
25 | pub fn cot(angle: T) -> T {
26 | unimplemented!()
27 | }
28 |
29 | pub fn coth(angle: T) -> T {
30 | unimplemented!()
31 | }
32 |
33 | pub fn csc(angle: T) -> T {
34 | unimplemented!()
35 | }
36 |
37 | pub fn csch(angle: T) -> T {
38 | unimplemented!()
39 | }
40 |
41 | pub fn sec(angle: T) -> T {
42 | unimplemented!()
43 | }
44 |
45 | pub fn sech(angle: T) -> T {
46 | unimplemented!()
47 | }
48 |
--------------------------------------------------------------------------------
/nalgebra-glm/src/gtc/ulp.rs:
--------------------------------------------------------------------------------
1 | use na::{Scalar, U2};
2 |
3 | use crate::aliases::TVec;
4 |
5 | pub fn float_distance(x: T, y: T) -> u64 {
6 | unimplemented!()
7 | }
8 |
9 | pub fn float_distance2(x: &TVec2, y: &TVec2) -> TVec {
10 | unimplemented!()
11 | }
12 |
13 | pub fn next_float(x: T) -> T {
14 | unimplemented!()
15 | }
16 |
17 | pub fn next_float2(x: T, Distance: u64) -> T {
18 | unimplemented!()
19 | }
20 |
21 | pub fn prev_float(x: T) -> T {
22 | unimplemented!()
23 | }
24 |
25 | pub fn prev_float2(x: T, Distance: u64) -> T {
26 | unimplemented!()
27 | }
28 |
--------------------------------------------------------------------------------
/nalgebra-glm/src/gtx/exterior_product.rs:
--------------------------------------------------------------------------------
1 | use crate::aliases::TVec2;
2 | use crate::traits::Number;
3 |
4 | /// The 2D perpendicular product between two vectors.
5 | pub fn cross2d(v: &TVec2, u: &TVec2) -> T {
6 | v.perp(u)
7 | }
8 |
--------------------------------------------------------------------------------
/nalgebra-glm/src/gtx/handed_coordinate_space.rs:
--------------------------------------------------------------------------------
1 | use crate::aliases::TVec3;
2 | use crate::traits::Number;
3 |
4 | /// Returns `true` if `{a, b, c}` forms a left-handed trihedron.
5 | ///
6 | /// # See also:
7 | ///
8 | /// * [`right_handed()`]
9 | pub fn left_handed(a: &TVec3, b: &TVec3, c: &TVec3) -> bool {
10 | a.cross(b).dot(c) < T::zero()
11 | }
12 |
13 | /// Returns `true` if `{a, b, c}` forms a right-handed trihedron.
14 | ///
15 | /// # See also:
16 | ///
17 | /// * [`left_handed()`]
18 | pub fn right_handed(a: &TVec3, b: &TVec3, c: &TVec3) -> bool {
19 | a.cross(b).dot(c) > T::zero()
20 | }
21 |
--------------------------------------------------------------------------------
/nalgebra-glm/src/gtx/matrix_cross_product.rs:
--------------------------------------------------------------------------------
1 | use crate::aliases::{TMat3, TMat4, TVec3};
2 | use crate::RealNumber;
3 |
4 | /// Builds a 3x3 matrix `m` such that for any `v`: `m * v == cross(x, v)`.
5 | ///
6 | /// # See also:
7 | ///
8 | /// * [`matrix_cross()`]
9 | pub fn matrix_cross3(x: &TVec3) -> TMat3 {
10 | x.cross_matrix()
11 | }
12 |
13 | /// Builds a 4x4 matrix `m` such that for any `v`: `m * v == cross(x, v)`.
14 | ///
15 | /// # See also:
16 | ///
17 | /// * [`matrix_cross3()`]
18 | pub fn matrix_cross(x: &TVec3) -> TMat4 {
19 | crate::mat3_to_mat4(&x.cross_matrix())
20 | }
21 |
--------------------------------------------------------------------------------
/nalgebra-glm/src/gtx/mod.rs:
--------------------------------------------------------------------------------
1 | //! (Reexported) Experimental features not specified by GLSL specification.
2 |
3 | pub use self::component_wise::{comp_add, comp_max, comp_min, comp_mul};
4 | //pub use self::euler_angles::*;
5 | pub use self::exterior_product::cross2d;
6 | pub use self::handed_coordinate_space::{left_handed, right_handed};
7 | pub use self::matrix_cross_product::{matrix_cross, matrix_cross3};
8 | pub use self::matrix_operation::{
9 | diagonal2x2, diagonal2x3, diagonal2x4, diagonal3x2, diagonal3x3, diagonal3x4, diagonal4x2,
10 | diagonal4x3, diagonal4x4,
11 | };
12 | pub use self::norm::{distance2, l1_distance, l1_norm, l2_distance, l2_norm, length2, magnitude2};
13 | pub use self::normal::triangle_normal;
14 | pub use self::normalize_dot::{fast_normalize_dot, normalize_dot};
15 | pub use self::quaternion::{
16 | mat3_to_quat, quat_cross_vec, quat_extract_real_component, quat_fast_mix, quat_identity,
17 | quat_inv_cross_vec, quat_length2, quat_magnitude2, quat_rotate_vec, quat_rotate_vec3,
18 | quat_rotation, quat_short_mix, quat_to_mat3, quat_to_mat4, to_quat,
19 | };
20 | pub use self::rotate_normalized_axis::{quat_rotate_normalized_axis, rotate_normalized_axis};
21 | pub use self::rotate_vector::{
22 | orientation, rotate_vec2, rotate_vec3, rotate_vec4, rotate_x_vec3, rotate_x_vec4,
23 | rotate_y_vec3, rotate_y_vec4, rotate_z_vec3, rotate_z_vec4, slerp,
24 | };
25 | pub use self::transform::{rotation, rotation2d, scaling, scaling2d, translation, translation2d};
26 | pub use self::transform2::{
27 | proj, proj2d, reflect, reflect2d, scale_bias, scale_bias_matrix, shear2d_x, shear2d_y, shear_x,
28 | shear_y, shear_z,
29 | };
30 | pub use self::transform2d::{rotate2d, scale2d, translate2d};
31 | pub use self::vector_angle::angle;
32 | pub use self::vector_query::{
33 | are_collinear, are_collinear2d, are_orthogonal, is_comp_null, is_normalized, is_null,
34 | };
35 |
36 | mod component_wise;
37 | //mod euler_angles;
38 | mod exterior_product;
39 | mod handed_coordinate_space;
40 | mod matrix_cross_product;
41 | mod matrix_operation;
42 | mod norm;
43 | mod normal;
44 | mod normalize_dot;
45 | mod quaternion;
46 | mod rotate_normalized_axis;
47 | mod rotate_vector;
48 | mod transform;
49 | mod transform2;
50 | mod transform2d;
51 | mod vector_angle;
52 | mod vector_query;
53 |
--------------------------------------------------------------------------------
/nalgebra-glm/src/gtx/normal.rs:
--------------------------------------------------------------------------------
1 | use crate::RealNumber;
2 |
3 | use crate::aliases::TVec3;
4 |
5 | /// The normal vector of the given triangle.
6 | ///
7 | /// The normal is computed as the normalized vector `cross(p2 - p1, p3 - p1)`.
8 | pub fn triangle_normal(p1: &TVec3, p2: &TVec3, p3: &TVec3) -> TVec3 {
9 | (p2 - p1).cross(&(p3 - p1)).normalize()
10 | }
11 |
--------------------------------------------------------------------------------
/nalgebra-glm/src/gtx/normalize_dot.rs:
--------------------------------------------------------------------------------
1 | use crate::RealNumber;
2 |
3 | use crate::aliases::TVec;
4 |
5 | /// The dot product of the normalized version of `x` and `y`.
6 | ///
7 | /// This is currently the same as [`normalize_dot()`]
8 | ///
9 | /// # See also:
10 | ///
11 | /// * [`normalize_dot()`]
12 | pub fn fast_normalize_dot(x: &TVec, y: &TVec) -> T {
13 | // XXX: improve those.
14 | x.normalize().dot(&y.normalize())
15 | }
16 |
17 | /// The dot product of the normalized version of `x` and `y`.
18 | ///
19 | /// # See also:
20 | ///
21 | /// * [`fast_normalize_dot()`]
22 | pub fn normalize_dot