# 2D & 3D vector operators

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

## 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 on other sites
Quote:
 Original post by vicviperI'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 on other sites
Quote:
Original post by ToohrVyk
Quote:
 Original post by vicviperI'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 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 on other sites
Quote:
 Original post by vicviperThen, there are less obvious operations that are more subject to discussion:< > <= >= ^ | & , etcMy 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 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 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 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 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 on other sites
Quote:
 Original post by nmiYou 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.

1. 1
Rutin
39
2. 2
3. 3
4. 4
5. 5

• 12
• 10
• 13
• 104
• 11
• ### Forum Statistics

• Total Topics
632983
• Total Posts
3009703
• ### Who's Online (See full list)

There are no registered users currently online

×