Thread: Operators for 3D Vector Mathematics

  1. #1
    Registered User Anarchist's Avatar
    Join Date
    Jan 2002
    Posts
    12

    Operators for 3D Vector Mathematics

    I'm writing a graphics program that uses 3D vectors, I have an existing library that I've written that already contains all the code for vector manipiulation but it was written in C using a struct to define a vector and funtions to manipulate them.
    I now have a Vector class as I'm writing in C++ and rather than have to call a funtion which makes the code less readable I'd like to overload the operators, the only problem is I dont know how to write the function headers for the operator overloading for what I need or if its possable for some of it. this is whats needed

    Vector + Vector = Vector
    Vector - Vector = Vector
    Vector x Vector = Vector (Cross product)
    Vector . Vector = float (Dot product)
    Vector * float = Vector (Scaling)
    Vector = Vector

    also if I'm using pointers to the vector class would I need to dereference the pointer to use the operators?

    I'm not to sure how operator over loading works but would a line like this

    Code:
    CVector operator + (CVector &v2)
    be processed as
    Code:
    return type =  this + v2

  2. #2
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    Unless I'm mistaken, the STL already has this covered. Look up info on the valarray templated object. There are a few problems with using it, the people who introduced the concept to the C++ standard library left the committee before the standard was finished so it tends to have an unpolished feel, but hey... you can work around that can't you?
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  3. #3
    pronounced 'fib' FillYourBrain's Avatar
    Join Date
    Aug 2002
    Posts
    2,297

    Re: Operators for 3D Vector Mathematics

    Originally posted by Anarchist
    also if I'm using pointers to the vector class would I need to dereference the pointer to use the operators?
    yup, that's about right. use references when you can though. for instance:

    CVector *myptr;
    //some stuff to get the pointer
    CVector & alias = *myptr;

    something = alias + blah;




    since you have alias as a reference instead of a pointer you can use the thing without dereferencing explicitly.

    of course you could always do a bunch of other things...

    myptr->operator+() can be called
    (*myptr) + blah //you already knew that.
    "You are stupid! You are stupid! Oh, and don't forget, you are STUPID!" - Dexter

  4. #4
    Registered User Anarchist's Avatar
    Join Date
    Jan 2002
    Posts
    12
    The STL valarray looked far too complicated, and what I did understand didnt apear to do what I wanted. I'm not sure which would have been easiest changing my existing code to use a new type or writing the extra bits I need now ( I have a very bad programming style - I write bits as I need them) my vectors are defined and have constructors and the accessors I needed ( probably a bad idea as theyre just getting on my nerves I should have just ignored my OOP tutor when he said all member variables should be private with accessors) but I havnt made the actual manipulation code yet as I've only just got to the point in my program where I need it. So it looks like I'll have to rake out my old program n use the functions or do the same and overload the operators.

    Thanks for the tip hk_mp5kpdw if I ever manage to understand the STL or templates in general I may use the valarray in a later program. I think I've missed out on a lot of what makes c++ by learning it from the appendix of a windows games book and what 've managed to pick up from the MSVC++ documentation

    Thanks FillYourBrain for explaining that all the sources I've seen have never really covered that, I'm begingin to think that I dont really need the massive amout of pointers that I use in my programs

  5. #5
    Registered User
    Join Date
    Jan 2003
    Posts
    311
    valarray is not exactly a replacement for a 3d vector class, particularly your own. There is a paper on the web by the guy who wrote it, an interesting read. To overload operators (and you can't overload . sorry) the usual way is to first overload the assignment version.

    Code:
    class Vector {
    ...
        Vector & operator += (const Vector &rhs) 
        {
            x += rhs.x; y += rhs.y; z = rhs.z;
    // or x() += rhs.x(); y() += rhs.y(); z() += rhs.z();
            return *this;
        }
    };
    // then, for sugar, make a binary version
    inline Vector operator +(const Vector &lhs, const Vector &rhs) {
        return Vector(lhs)+=rhs;
    }
    The binary + invokes the copy constructor at least once, possibly twice. There is a nifty trick in The C++ Programming Language section 22.4.7 that details how to reduce temporaries and copying.

    Fill your brain, holding references to pointers is almost always bad news. The assembly generated will be identical but you now have a way to unexpectedly delete something held in a reference.

    As to public members/accessors don't worry about it. The main reason you want to make something private is so that you can change it later. Common ways to do 3Dvector are to either have explicit public members x,y,z or something like this
    Code:
    class vec3D {
        enum {xpos=0, ypos=1, zpos=2};
    public:
        vec3D(const vec3D &vec) {
            memcpy(v,vec.v,sizeof(v));
        }
        typedef double scalar;
        scalar & x() {reutrn v[xpos];}    
        scalar & y() {reutrn v[ypos];}    
        scalar & z() {reutrn v[zpos];}    
    private:
        scalar v[3];
    };
    Some things may be faster in terms of v, but you still have easily readable operations.

  6. #6
    pronounced 'fib' FillYourBrain's Avatar
    Join Date
    Aug 2002
    Posts
    2,297
    references ARE pointers. if you've done the appropriate checks and are careful (as you must be with all pointers) you will not have an issue. as far as the aliasing scenario I mentioned, it's an extreme case and probably not necessary when you can just pass a reference into the function to begin with. References are far cleaner syntax than pointers most of the time.
    "You are stupid! You are stupid! Oh, and don't forget, you are STUPID!" - Dexter

  7. #7
    Registered User Anarchist's Avatar
    Join Date
    Jan 2002
    Posts
    12
    Thanks for the tips, I shoudl be able to get things going now

  8. #8
    Registered User
    Join Date
    Jan 2003
    Posts
    311
    It's a style thing I guess, but to me a reference to a value addressed by a pointer cleans up things that should be ugly. If you need the functionality of the pointer then use it, if you need an alias use a reference. Keep in mind also that while a reference CAN be a pointer, the comiler is going to do it's level best to avoid doing so.

    int i=7;
    int *p = &i;
    int &r = i;
    int a = *p + 3; // generates deref
    int b = r + 3; // can generate identical code to i + 3;
    int &r2 = *p;
    int c = r2 + 3; // will almost always deref, but looks normal

  9. #9
    Registered User Anarchist's Avatar
    Join Date
    Jan 2002
    Posts
    12

    Same subject Different problem

    when compiling my code I get the error
    error C2679: binary '*' : no operator defined which takes a right-hand operand of type 'const float' (or there is no acceptable conversion)
    the 1 line of code that causes this is infact the second line that uses vector scaling
    Code:
    			*polyNormal=( (*Triangle->GetVertex(FIRST)->GetNormal()) * (1-(alpha+beta)) )+
    				((*Triangle->GetVertex(SECOND)->GetNormal()) * alpha )+
    				((*Triangle->GetVertex(THIRD)->GetNormal()) * beta);
    this basically boils down to vector= (vector * float) +(vector * float) +(vector * float)
    at first glance you'd think I havnt written the code for the operator but an earlier line that uses it compiles fine

    Code:
    		*position = *m_Start + (*m_Direction * t);
    this being Vector = Vector + (Vector * float)
    I can't see why these lines of code should be treated differently
    could the problem be because I use function calls to get a pointer to the Vector(GetNormal) and then dereference this?

    Interestingly enough if I replace the 1-(alpha+beta) with a variable of type float it works, could anyone explain this behaviour?

    if it helps the operator for scaling id defined as
    Code:
    	CVector operator * (float &val); //scale

  10. #10
    Registered User
    Join Date
    Jan 2003
    Posts
    311
    The short answer is just use
    CVector operator * (float val); //scale
    or possibly
    CVector operator * (const float &val); //scale
    In general pass normal scalar plain old data(float,char,int) by value and classes or complicated stuff as a reference to const.

    The reason your compiler is complaining is because you cannot take a non-const reference to a temporary. (1-(alpha+beta)) results in a temporary float being generated, two actually, one for the result of alpha+beta and another to hold 1 minus the previous temporary.

  11. #11
    Banned
    Join Date
    Jan 2003
    Posts
    1,708
    Hey anarchist I dont' know how interested you are in math, nor do I know what you already know, but this is a really good book dealing with all aspects of 3d computer programming. It assumes trig and calculus experience, however. I bought this book a few days ago and have been reading through it and I am very satisfied with its content (I estimate I'll personally be reading it for a year before I can say I have good command of all the content). It explains everything in as much detail you could ask for, contains appendices for reference (i.e important trig stuff such as law of sines and cosines and all of the other basic stuff) and shows simple implementations using opengl (and I'm not sure what language, actually looks like assembly because it says 'mov' in there )

    http://www.amazon.ca/exec/obidos/ASI...152163-2461153

    Anyway read the book description and you'll find it contains everything you'd want to know and im going to stfu now

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Logical Operators in C++
    By Flecto in forum C++ Programming
    Replies: 4
    Last Post: 05-15-2009, 07:17 AM
  2. Bolean Operators hurt my head. (Trouble understanding) :(
    By Funcoot in forum C++ Programming
    Replies: 3
    Last Post: 01-20-2008, 07:42 PM
  3. operators???
    By arjunajay in forum C++ Programming
    Replies: 11
    Last Post: 06-25-2005, 04:37 AM
  4. Operators
    By George in forum C++ Programming
    Replies: 3
    Last Post: 04-02-2003, 07:35 PM
  5. operators operands
    By verb in forum C Programming
    Replies: 6
    Last Post: 02-13-2002, 07:04 PM