Jump to content
  • Advertisement
Sign in to follow this  
vicviper

2D & 3D vector operators

This topic is 4079 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, At work I had to implement a 3D vector for the Nth time, and some questions about which operators to implement arised. basically, we have a vector like this: struct vector3D { float x,y,z; }; and we have implemented the obvious operators: = + - * / *= += == , etc Then, there are less obvious operations that are more subject to discussion: < > <= >= ^ | & , etc My question is: is there a more mathematically correct, or more standard, or coommon way to implement them? or they're just subject to the free will of every developer? For example, I've seen some vectors that have the Cross Product and Dot Product implemented as named methods, while others implement them with the | and ^ operators... is this common/standard? I've also seen the comparison operators implemented like this: bool operator < (right) { return x < right.x && y < right.y && z < right.z } And to me it looks correct and on par with the == operator, but to me, other implementations would be more useful... So, what you people do about these ones? Btw, here They're trying to make a standard math library for games: http://www.convexhull.com/wiki/?n=GameMath.HomePage

Share this post


Link to post
Share on other sites
Advertisement
Quote:
Original post by vicviper
I've also seen the comparison operators implemented like this:

bool operator < (right) { return x < right.x && y < right.y && z < right.z }


It's incorrect, because it's not a complete order (and operator < is universally accepted to be complete).

Share this post


Link to post
Share on other sites
Quote:
Original post by ToohrVyk
Quote:
Original post by vicviper
I've also seen the comparison operators implemented like this:

bool operator < (right) { return x < right.x && y < right.y && z < right.z }


It's incorrect, because it's not a complete order (and operator < is universally accepted to be complete).


Ok, so which would be the correct implementation of operator < ? or, it is not possible on a vector?

Share this post


Link to post
Share on other sites
There is no one which makes sense in any geometric way. However, you can still provide a complete order relationship, which is kind of arbitrary: the lexicographic order.

Share this post


Link to post
Share on other sites
Quote:
Original post by vicviper
Then, there are less obvious operations that are more subject to discussion:

< > <= >= ^ | & , etc

My question is: is there a more mathematically correct, or more standard, or coommon way to implement them? or they're just subject to the free will of every developer?

You are not required to implement every operator. Just implement those that make sense for your type. For a 3D-vector operator> has no common meaning, so don't implement it. (You could make it a shortcut for comparing lengths of vectors, but then the code becomes unreadable, so don't do it.)
Quote:

For example, I've seen some vectors that have the Cross Product and Dot Product implemented as named methods, while others implement them with the | and ^ operators... is this common/standard?

Which product should be used for operator* ? Ask yourself, the inner (dot) product or the outer (cross) product ? Calling a function by name makes it clear.

Share this post


Link to post
Share on other sites
Quote:

Quote:

For example, I've seen some vectors that have the Cross Product and Dot Product implemented as named methods, while others implement them with the | and ^ operators... is this common/standard?

Which product should be used for operator* ? Ask yourself, the inner (dot) product or the outer (cross) product ? Calling a function by name makes it clear.

nmi, the * operator needs to be implement for multiplications with scalars ;). As fot the >= <= > < operators, i personally whould make 4 functions so that it would be clearer what i am intending to do.
for example if you want to compare elementwise, you can make a function with the name
EWCmpGE(Vec3 &v1, Vec3 &v2), whose name is a short for "elementwise comparison greater or equal"
you can use GT for "greater", LT for less, and LE fot less or equal, like in fortran :). it may not be so "beautiful" as the operators, but the names are still short, descriptive, and you are not mathematically incorrect.

Share this post


Link to post
Share on other sites
You can still overload the * operator for dot or cross product, but it can be misleading. Some libraries used it for the cross product others for the dot product. I generally use * for the dot product and the & or the ^ operator for the cross product.

You also have to be careful with operator precedence.

Share this post


Link to post
Share on other sites
I typically overload operator* to take a vector or a scalar as an argument; it's usually pretty clear which one is being used. I recommend implementing dot() and cross() as well though, since some people expect those functions.

operator/ I use for scalars, or to mean a cross product in reversed order * -1. The latter comes in handy for long expressions.

As far as comparisons, I use them to compare the magnitude of a vector. It usually comes into play when sorting a std::vector of Vector3D to find the nearest objects, etc. Also I recommend having a static Vector3D::epsilon for your comparisons, because as I'm sure you know A*3.0f-A*2.0f rarely equals A.

operator= I use to either copy a vector or reassign its magnitude.

I don't touch the bitwise operators though; there's no situation where a clear meaning has come up.

Share this post


Link to post
Share on other sites

From what I can read from everybody's responses, it is not wise to implement the < <= >= > operators since everybody would expect something different from them, and they can be misleading.

Now I noticed something else:

Some of you implement the * operator as a dot product, that is:

float operator * (vector) { x*vector.x + y*vector.y + z*vector.z }

While I think others just implement a component per component multiply:

vector operator * (vector) { x*vector.x , y*vector.y , z*vector.z }

Performing it as a dot product looks like more mathematically correct, but
I can see times where what you need is just multiply component per component,
and when you want a dotproduct, do it specifically with the .dot() method


Share this post


Link to post
Share on other sites
Quote:
Original post by nmi
You are not required to implement every operator. Just implement those that make sense for your type. For a 3D-vector operator> has no common meaning, so don't implement it. (You could make it a shortcut for comparing lengths of vectors, but then the code becomes unreadable, so don't do it.)

Just because there is no common or logical meaning doesn't mean there isn't a practical reason for implementing it. For instance, implementing the less-than operator allows you to store the vector in a number of different sorted containers and otherwise use sorting methods on lists of vectors. Why would you want to sort vectors if there is no logical ordering? One purpose would be to remove duplicate vertexes. Using the lexicographic order, you can easily sort vertexes and remove adjacent duplicates in O(n log n).

Vector-vector multiplication is an opt-debated operation, since some people think it isn't well-defined enough to implement. I personally implement it as a component-wise multiplication, however that's simply because I've done a lot of shader programming in the past few months and it makes the most sense to me. I don't use operators for the dot and cross product because it feels way too arbitrary to me, but again that's just personal preference.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!