glam-rs icon indicating copy to clipboard operation
glam-rs copied to clipboard

Respect precision format specifiers in Vec3::display

Open ten3roberts opened this issue 2 years ago • 5 comments

Currently, the floating point value is display in full, which creates way too many decimals than are necessary for displaying e.g; position.

If it is not possible to respect format precision, it would be better if a precision of e.g 4 or 5 was used.

Example:

[ 0.000000323, 0.0233232, 3.42323 ]
rather than
[ 0.0, 0.0233, 3.423 ]

ten3roberts avatar Jan 14 '22 09:01 ten3roberts

I think this is rather subjective. In some cases, floating point equality is useful (often when comparing against 0.0) and the example you gave would make this highly confusing if you were debugging something that wasn't working as expected.

aloucks avatar Jan 14 '22 17:01 aloucks

I think I know what you are getting at @ten3roberts but it might help to include example code.

bitshifter avatar Jan 15 '22 08:01 bitshifter

Of course.

The following example demonstrated the slight problem I am having

    let pos = Vec3::new(0.00000000000004, 0.5, 1.0);
    println!("Pos: {:.2}", pos); // Pos: [0.000000000004, 0.5, 1]
    println!("Pos: [{:.2}, {:.2}, {:.2}]", pos.x, pos.y, pos.z); // -> Pos: [0.00, 0.50, 1.00]

It happens in physics simulations where you have something slowing down but never due to a proportional force, and I would like to round the result. E.g where lim x->inf f = 0

image

The code for that example

write!(
    f,
    concat!(
        "frametime: {:.<7.1?} | {:>2.1}/s\n",
        "elapsed: {:.2?}\n",
        "pos: {:.2}\n",
        "vel: {:.2}\n",
    ),
    self.frametime,
    1.0 / self.frametime.as_secs_f32(),
    self.elapsed,
    self.pos,
    self.vel,
)?;

Ok(())

ten3roberts avatar Jan 15 '22 09:01 ten3roberts

I noticed that Debug printing will respect the precision values because the way it is implemented is different to Display.

You can kind of work around this to get what you want:

use glam::*;

fn main() {
    let f = 1.000123;
    let v = Vec2::new(f, f + f);
    println!("{}", f);
    println!("{:.2}", f);

    println!("{}", v);
    println!("{:.2?}", v);
    println!("{:.2?}", v.as_ref());
}

prints

1.000123
1.00
[1.000123, 2.000246]
Vec2(1.00, 2.00)
[1.00, 2.00]

So you can get the output that you want with the last one :)

It should be possible to make Display use the precision value, it just looks a bit verbose implementation wise unfortunately.

bitshifter avatar Jan 15 '22 10:01 bitshifter

I suppose the above trick works because as_ref converts the vector to a slice.

In that case, the display trait could be implemented to just forward to the slice Display implementation, which means we will get all the features and formats correctly.

ten3roberts avatar Jan 16 '22 10:01 ten3roberts