-
Notifications
You must be signed in to change notification settings - Fork 103
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Separate Point and Vector types #159
Conversation
Once again, this is a pretty invasive breaking change. I think that it is worth it, as I have plenty of bug stories about confusing positions and offsets in space, but we should make sure the interested parties all agree about this before landing anything. I am pretty tempted to rename Matrix4D into Matrix3D at the same time. It makes more sense since it expresses 3D transformations, just like Matrix2D expresses 2D transformation and is not a 2x2 matrix. Also, about the added square_norm and norm methods: I am personally more used to "length", but I anticipated that the naming would collide with length::Length. If you prefer length, I'll be happy to change the name. |
A motivating example of where this could be useful is implementing SVG. The latter is full of relative and absolute coordinates, see this SVG paths building interface for example. In this library I have Point and Vec2 aliases which are the same underlying euclid Point2D. Having the the aliases helped clarify the API a bit, but didn't prevent me from forgetting to do the right thing when working with relative coordinates in a lot of places. |
Renaming Is there a better name, along the lines of |
How is it more confusing than Matrix2D not being a 2x2 matrix? |
I didn't mean to change the structure of Matrix4D (no change to m14 m24 m34 and m44), just the name to reflect that it is a matrix for 3D transformations. Also, my PR removes the Point4D type so Matrix4D ends up the only thing labelled as 4D. AffineTransform3D is very accurate name but it's a bit of a mouthful and not a name I would think about searching for if I discovered the crate. Tranform3D would be fine, though. |
Since there isn't a clear consensus on matrix names, we should probably continue this part of the discussion in a separate issue. |
Fair enough. I hadn't used the 2D objects and didn't notice! |
cc @mrobinson |
☔ The latest upstream changes (presumably #165) made this pull request unmergeable. Please resolve the merge conflicts. |
This is exactly what cgmath and nalgebra do. 👍 |
I'd like to revive this. The PR has been rebased, athough I took out the part about removing Point4D to reduce the amount of churn (I still think we should remove it, but we can talk about that separately). r? @glennw |
@@ -72,7 +72,10 @@ pub use matrix4d::{Matrix4D, TypedMatrix4D}; | |||
pub use point::{ | |||
Point2D, TypedPoint2D, | |||
Point3D, TypedPoint3D, | |||
Point4D, TypedPoint4D, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You removed the reexport and I don't think that was intended. Was it?
☔ The latest upstream changes (presumably #170) made this pull request unmergeable. Please resolve the merge conflicts. |
Let me express a different point of view here. On matrices
Exactly, let's fix this. Instead of renaming The problem here is semantics. Matrix in general is just doing a linear transformation. Matrix by itself doesn't transform points. You can say that it can produce an affine transformation of a point by linearly transforming a homogeneous vector form of that point, but that's thinking on a higher level. So when naming things, we should be clear about what semantic level is the name in. If we want to operate on the level of the basic algebra, then 4x4 matrix should be called
That sounds more like a transform domain (the latter choice with On vectors and pointsConsequently, the choice of having Vector/Point or just Point can be derived from the chosen domain. If all you have is fn to_point_homogeneous(&self) -> Point4<T> {..}
fn to_vector_homogeneous(&self) -> Point4<T> {..} If you have |
Euclid tries to be a library to represent and transform geometry. The matrix types happen to be matrices but we really reason about transforms (preferring terminology like I would very much like to revive this (vector/point separation and naming) by the way. I'll happily rebase my PRs if we are willing to land them. |
@nical Ok, good, looks like we are in agreement then. |
I am reviving this. I ended up re-doing the change so it is still a work in progress although it is almost complete. |
☔ The latest upstream changes (presumably #194) made this pull request unmergeable. Please resolve the merge conflicts. |
The more I look at it, the more I become obsessed with an idea that Reviewed 7 of 7 files at r2. src/point.rs, line 121 at r2 (raw file):
src/point.rs, line 386 at r2 (raw file):
src/point.rs, line 438 at r2 (raw file):
I don't think we should have a cross product between points src/point.rs, line 440 at r2 (raw file):
indentation is off src/rect.rs, line 162 at r2 (raw file):
src/transform3d.rs, line 391 at r2 (raw file):
I don't think handling 2D points/vectors by a 3D transformation is useful:
src/transform3d.rs, line 415 at r2 (raw file):
correspondingly, this would just be called src/transform3d.rs, line 438 at r2 (raw file):
this one got me into trouble once. Perhaps, rename it to src/vector.rs, line 1 at r2 (raw file):
let's jump out of the past src/vector.rs, line 16 at r2 (raw file):
I don't think this is idiomatic src/vector.rs, line 38 at r2 (raw file):
let's use src/vector.rs, line 39 at r2 (raw file):
and src/vector.rs, line 51 at r2 (raw file):
Should we put the type name in here as well? As in, src/vector.rs, line 78 at r2 (raw file):
I'd propose to build the type hierarchy bottom-up. Thus, vectors are self-sufficient and don't depend on anything. Points and sizes depend on them and define conversions to/from vectors from within. src/vector.rs, line 100 at r2 (raw file):
src/vector.rs, line 119 at r2 (raw file):
src/vector.rs, line 123 at r2 (raw file):
Maybe "magnitude" instead of "norm" here? src/vector.rs, line 140 at r2 (raw file):
Similarly, I don't recall seeing "norm" used for the length. You can call it "magnitude" (or "mag") or "length", but I don't see "norm" to be appropriate src/vector.rs, line 174 at r2 (raw file):
is there a use-case for it? It's not obvious to me that we need it src/vector.rs, line 181 at r2 (raw file):
why do we need this if we have src/vector.rs, line 266 at r2 (raw file):
Similarly, I'm curious about where do we ever need to src/vector.rs, line 474 at r2 (raw file):
indentation src/vector.rs, line 489 at r2 (raw file):
same concern about the "norm" here Comments from Reviewable |
I would rather not, because I often print out large buffers of points and vectors and the extra letters make it harder to read (when there's many of them). The word magnitude rubs me the wrong way (even if it means the same thing). If you prefer we can call it I have my own use cases for floor/ceil/round in vectors, when I do some of the computation with integers instead of floats. Might not be used by servo but i'd like to keep them. On the topic of using cgmath, nalgebra or some other established math library, none of them seem interested in treating vector spaces as a first class citizen (the U phantom type in euclid) this feature is very important for us and it alone justifies having a separate library. Anyway, I don't want to revive this topic in this PR, let's talk about it in a separate issue or on irc if you are interested. |
I see your point. You may use
Out of curiosity, is
Could you share them? Just to get a bigger picture of the use case space.
Agreed, moved to #197 |
Norm and magnitude are synonyms. Depending on who your math teacher was you may have run into one more than the other in english (perhaps there are some biases depending on which side of the ocean you are on, I do remember hearing
Some algorithms rely on being able to reason about precision, and it is very hard to do with floating point numbers. Working with integers (or fixed-point numbers) gives you something where the precision loss is mostly constant or at least something you can reason about (at the cost of having to be very careful with overflows). Lyon's tessellator is an example of this (I don't want to flood this PR with the details but I could go on about this for ever, I'll tell you all about it over a beer in SF if you are interested), I know that working with integer spaces is also very popular for the same reasons when doing things like nav-meshes and lots of geometry processing algorithms in general. When going from floating point to the "fixed precision" space of the algorithm, it's useful to be able to explicitly choose the way you want to go about snapping quantities (be it vectors or points) to the integer space. |
I just took another stab at googling it and found the confirmation:
TL;DR: This is convincing, I'm fine with either
Right, I recall that you've been doing lots of integer work in @nox would you want to take a look at the PR as well? |
FWIW I would disagree with `length()`, because it's `len()` everywhere else
in Rust. I'd lean towards `size` or `len`, to be more Rustaceous.
…On 25 May 2017 at 17:22, Dzmitry Malyshau ***@***.***> wrote:
Norm and magnitude are synonyms.
I just took another stub at googling it and found the confirmation:
A simple example is two dimensional Euclidean space R2 equipped with the
Euclidean norm. Elements in this vector space (e.g., (3, 7)) are usually
drawn as arrows in a 2-dimensional cartesian coordinate system starting at
the origin (0, 0). The Euclidean norm assigns to each vector the length of
its arrow. Because of this, the Euclidean norm is often known as the
magnitude.
TL;DR: norm() is generally an abstract function in specific space having
specific properties. In Euclidean space though, it's clearly defined as
what we know as length/magnitude. And since the library happens to be
called euclid, it would make sense to have the norm.
This is convincing, I'm fine with either norm/length/magnitude now.
Working with integers (or fixed-point numbers) gives you something where
the precision loss is mostly constant or at least something you can reason
about
Right, I recall now that you've been doing lots of integer work in lyon.
My concern with vector rounding is that a lot of operations in vector space
are not transitive with regards to rounding, e.g. ceil(a+b) != ceil(a) +
ceil(b). Thus, defining it on points, which are more restricted, sound a
little better to me. But I won't lose my sleep over it, I'm fine with
having the rounding defined for vectors too, if that's useful to you.
@nox <https://github.com/nox> would you want to take a look at the PR as
well?
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#159 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AAJNW-_B29jpCh8d5yU-fxqsXFiL4DS8ks5r9arPgaJpZM4JoPj2>
.
|
I don't think being consistent with the terminology used for the size of containers brings any value, and I passionately dislike abbreviating 6 letter words. Plus, maths are full of acronyms, so we I'd rather let names that are not english words be only for those. |
📌 Commit 614eeca has been approved by |
🔒 Merge conflict |
Rebased, @bors-servo r=@kvark |
📌 Commit f33d6e2 has been approved by |
Separate Point and Vector types This changeset implements my proposal from issue #151: - TypedVector2D and TypedVector3D types are added (no 4D vector) - Matrix types implement separate transformations for points and vectors - the 4D vector is removed, and along with it the bug-prone behavior of ignoring its w component half of the time. - Point arithmetic is changed so that: - Point + Point is not implemented - Point + Vector = Point - Point - Point = Vector With points and vectors as separate types, we don't need the 4D types anymore because the homogeneous coordinate is part type itself: for vectors it is always zero, and for points it is always one. Matrix transformations always divide the resulting points by w. It avoids the confusion that motivated the PR #157, where w was ignored in half of euclid because the code expected it to be equal to one. <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/euclid/159) <!-- Reviewable:end -->
☀️ Test successful - status-travis |
This changeset implements my proposal from issue #151:
With points and vectors as separate types, we don't need the 4D types anymore because the homogeneous coordinate is part type itself: for vectors it is always zero, and for points it is always one. Matrix transformations always divide the resulting points by w. It avoids the confusion that motivated the PR #157, where w was ignored in half of euclid because the code expected it to be equal to one.
This change is