Open wellcaffeinated opened 5 years ago
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],
)
}
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....
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);
}
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.
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.
Perhaps once i understand this all better I can contribute some more docs for total newbies like me.
That would be great!
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...
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:any insight appreciated :)