rustgd / cgmath

A linear algebra and mathematics library for computer graphics.
https://docs.rs/cgmath
Apache License 2.0
1.13k stars 155 forks source link

Add vector subtraction for all points #426

Closed Osspial closed 7 years ago

Osspial commented 7 years ago

PointN implements Add<VectorN>, so it seems natural that Sub<VectorN> should be implemented as well.

brendanzab commented 7 years ago

Not sure if this actually makes sense. You can think of vectors defining the 'difference' between points in space. So:

let start = Point3::new(1, 2);
let end = Point3::new(4, 5);
let translation: Vector3<_> = end - start;

assert_eq!(translation, Vector3::new(3, 3));

Adding a vector to a point corresponds with the reverse - ie. transforming a point by the supplied vector:

let start = Point3::new(1, 2);
let translation = Vector3::new(3, 3));
let end: Point3<_> = start + translation;

assert_eq!(translation, Point3::new(4, 5));
Osspial commented 7 years ago

I can get that, but I think point-vector subtraction makes sense when you think of subtraction as the addition of the negation of the vector. For most types you can currently do this:

let start = Point2::new(5, 5);
let translation = Vector2::new(1, 2);
let end: Point2<_> = start + -translation;

assert_eq!(end, Point2::new(4, 3));

However, this adds an extra step to an operation that's supported by the native numeric types with the Sub operator. The bigger issue is that this doesn't actually work when you're dealing with points and vectors of unsigned integers, because negation doesn't make sense for a type which can have no negative values. For those, you have to do subtraction manually on each field which adds unnecessary code clutter.

brendanzab commented 7 years ago

Hmm good points (hah!). Thoughts @sebcrozet? What would your thoughts be about adding vector space subtraction to the EuclideanSpace trait in alga? 😕

sebcrozet commented 7 years ago

Well I think this would be useful. Subtraction makes sense (as an abuse of notations) as long as the vector appears on the right-hand side. I did not add it to EuclideanSpace yet because this caused some weird conflicts with Sub<Point> in generic code (probably a bug in the compiler).

Regarding a the unsigned integer issue, vectors valued with unsigned integers are not part of vector space so they won't be usable with an euclidean space anyway.

cristicbz commented 7 years ago

For what it's worth, I've recently migrated rust-doom to cgmath and this has been a pain point for physics-y things:

  1. I want to 'undo' a timestep, by subtracting, say, velocity * timestep.
  2. Representing a box as center: Point3 and half_size: Vector3, the minimal coordinates are then min: center - half_size to max: center + half_size.
brendanzab commented 7 years ago

Based on the feedback here, I've decided to merge this. Thanks a bunch everyone!