dimensioned icon indicating copy to clipboard operation
dimensioned copied to clipboard

Question: working with nalgebra

Open wellcaffeinated opened this issue 5 years ago • 7 comments

I feel so inept at this. I appreciate the help.

I'm trying to create a helper function that will take an array slice and create a dimensioned nalgebra::Vector3 out of it... but i'm failing. This is what I've got so far:

fn dim_vector3<L, R>( unit_const :L, arr :[R ;3] ) ->
  na::Vector3<dim::typenum::Prod<L, R>>
where
  L: std::ops::Mul<R>
{
  na::Vector3::new( 
    unit_const * arr[0], 
    unit_const * arr[1], 
    unit_const * arr[2]
  )
}

any insight appreciated :)

wellcaffeinated avatar Jun 13 '19 22:06 wellcaffeinated

I would recommend that you read through the hard sphere section of dimensioned-examples. It covers using dimensioned with vectors -- if you find anything confusing or lacking there, please open a ticket. I would be happy to try to make it more clear!

It is likely that you will have more luck by placing units on the outside of na::Vector3, not the inside. (Which is discussed in the above mentioned examples).

That said, you can make that code compile by adding some trait bounds. The compiler tells you you need Debug, Copy, and PartialEq for the output type (which together form na::Scalar). Then, it will still give you some lifetime errors. These messages are less helpful, but can be resolved by bounding L and R by Copy.

This code compiles:

fn dim_vector3<L, R>(unit_const: L, arr: [R; 3]) -> na::Vector3<dim::typenum::Prod<L, R>>
where
    L: std::ops::Mul<R> + Copy,
    R: Copy,
    dim::typenum::Prod<L, R>: na::Scalar,
{
  na::Vector3::new(
    unit_const * arr[0],
    unit_const * arr[1],
    unit_const * arr[2],
  )
}

paholg avatar Jun 16 '19 01:06 paholg

And, for fun, you can clean it up a bit with the op! macro:

#[macro_use] extern crate typenum;

fn dim_vector3<L, R>(unit_const: L, arr: [R; 3]) -> na::Vector3<op!(L*R)>
where
    L: std::ops::Mul<R> + Copy,
    R: Copy,
    op!(L*R): na::Scalar,
{
  na::Vector3::new(
    unit_const * arr[0],
    unit_const * arr[1],
    unit_const * arr[2],
  )
}

This reminds me that I need to make that macro 2018 edition compatible....

paholg avatar Jun 16 '19 01:06 paholg

One of the things that makes combining dimensioned and nalgebra hard is that there are cases where the units of matrices are non-homogeneous. For example, if you have a 2D Point2<Meter<f64>> and you wanted to translate and rotate it, you'd multiply an augmented vector by a 3x3 matrix. The units would look like this:

[   1    1  m ]   [ m ]
[   1    1  m ] X [ m ]
[ 1/m  1/m  1 ]   [ 1 ]

I've struggled in the past trying to put units inside nalgebra types, like na::Point2<si::Meter<f64>>, so in most of my code I only use dimensioned for 1D problems. That said, I just tried putting units on the outside and the following worked. Maybe I'll revisit using nalgebra and dimensioned together in the future.

use dimensioned::si;
use nalgebra as na;

fn main() {
    let position = si::Meter::new(na::Point2::new(2.0, 0.0));
    let velocity = si::MeterPerSecond::new(na::Vector2::new(3.0, 1.0));
    let time = 12.0 * si::S;
    let rotation = si::Unitless::new(na::Rotation2::new(std::f64::consts::FRAC_PI_2));

    println!("Position: {}", position);
    println!("Velocity: {}", velocity);
    println!("Time: {}", time);
    println!("Rotation: {}", rotation);

    println!("End position: {}", position + rotation * velocity * time);
}

adeschamps avatar Jun 16 '19 16:06 adeschamps

Thank you both! This was so helpful. I feel like I'm missing out on some of the implementation details surrounding dimensioned. I read through the examples, but found them a bit hard to follow. Perhaps once i understand this all better I can contribute some more docs for total newbies like me.

wellcaffeinated avatar Jun 19 '19 22:06 wellcaffeinated

BTW if you just want a 3D vector type that works well with dimensioned, you could try

https://crates.io/crates/vector3d

Which I created for that purpose.

droundy avatar Jun 20 '19 15:06 droundy

Perhaps once i understand this all better I can contribute some more docs for total newbies like me.

That would be great!

paholg avatar Jun 20 '19 16:06 paholg

Thanks a lot for the guidance on using dimensioned with nalgebra. Did someone figure out how to use a "Isometry3" with dimensioned? I think the challenge here is that it consists of a rotation and a translation so simply wrapping it in sth like "Meter" breaks as soon as i want to multiply the Isometry with sth else...

v-morlock avatar Nov 16 '23 16:11 v-morlock