kvark / mint

Math Interoperability Types
MIT License
256 stars 20 forks source link

Add `map` method to all vector, matrix, and rotation types #46

Closed pengowen123 closed 5 years ago

pengowen123 commented 5 years ago

Fixes #40.

kvark commented 5 years ago

@pengowen123 before we proceed, could you share more details on the use case that this map enables?

pengowen123 commented 5 years ago

@kvark The main use for this is converting between types, such as when using f64 for physics simulation but converting to f32 for rendering. This is possible to do today by converting each field manually. but this makes it clearer and more convenient, especially for the larger matrix types. For example, compare

let transform = Matrix3 {
    x: Vector3 {
        x: transform.x.x as f32,
        y: transform.x.y as f32,
        z: transform.x.z as f32,
    },
    y: Vector3 {
        x: transform.y.x as f32,
        y: transform.y.y as f32,
        z: transform.y.z as f32,
    },
    z: Vector3 {
        x: transform.z.x as f32,
        y: transform.z.y as f32,
        z: transform.z.z as f32,
    },
};

with

let transform = transform.map(|x| x as f32);

Adding #[inline] to the new methods is probably a good idea so that it has no performance penalty. Also, if this were to be used for non-type conversion operations, the current implementation would copy the entire structure. For this case a separate set of methods for in-place modification would be more efficient, though perhaps supporting that use case would be out of scope.

kvark commented 5 years ago

Thank you for describing this! Where exactly would you be using that conversion?

I'm asking because mint is not about doing any transformations. You aren't expected to do anything other with mint types than converting to/from other math libraries.

pengowen123 commented 5 years ago

I was under the impression that mint was meant to be built on top of by other libraries, which made offering very basic functionality like this make more sense. If it is solely for conversion between types from different libraries, then this is probably not necessary because those libraries likely provide similar functions that could be used instead.

kvark commented 5 years ago

I was under the impression that mint was meant to be built on top of by other libraries

I'm not sure what you mean by "built on top" here. See the last sentence from the readme:

There are no operations defined for the types other than for the means of conversion from/into external types.

pengowen123 commented 5 years ago

I thought mint provided common data structures to be extended with traits by different math libraries so that users wouldn't have to perform so many conversions, but looking at the readme again I see I was mistaken. I think it could be made more clear though.

kvark commented 5 years ago

First of all, sorry about not realizing this earlier and providing you feedback only when you spent an effort writing down the code. Thank you for doing this!

The classical case today is: a library uses library X, exposes mint, and the user uses library Y. In this case no map should be needed.

Having traits somewhere with mint structures implementing them is an idea we've been slowly considering, but there isn't much demand for yet another math implementation, so we keep mint only for the interop.

pengowen123 commented 5 years ago

No worries, it could still be useful if you decide to expand the library someday.