-4

So I was implementing my own Quaternion Class and I ran into a problem I wasn't expecting when calling one of my operator (static) functions from a member function. See function rotateByVector();

class Quaternion
{
    public:

        double x, y, z, w;

        Quaternion(double w, double xi, double yj, double zk)
        {
            w = w;
            x = xi;
            y = yj;
            z = zk;
        }

        Quaternion operator +(Quaternion q1, Quaternion q2)
        {
            return Quaternion(q1.w + q2.w, q1.x + q2.x, q1.y + q2.y, q1.z + q2.z);
        }

    Quaternion operator*(Quaternion q1, Quaternion q2)
    {
        return Quaternion(q1.w * q2.w - q1.x * q2.x - q1.y * q2.y - q1.z * q2.z
            , q1.w * q2.x + q1.x * q2.w + q1.y * q2.z - q1.z * q2.y
            , q1.w * q2.y + q1.y * q2.w + q1.z * q2.x - q1.x * q2.z
            , q1.w * q2.z + q1.z * q2.w + q1.x * q2.y - q1.y * q2.x);
    }

    void rotateByVector(double x1, double y1, double z1, double[3] res)
    {
        // want to calculate Hamilton Product
        // res_quaternion = this_quaternion * quaternion_vector(0, x1, y1, z1) * this_conj;
        // return double[3] {res_quaternion.x, res_quaternion.y, res_quaternion.z}

        Quaternion q = Quaternion(0.0f, x1, y1, z1);
        Quaternion r = (*this).operator*() q; //doesn't like it
        Quaternion r = this->operator*(q); //doesn't like it either
        ...
        r = r * this.conj();
        res[0] = r.x;
        res[1] = r.y;
        res[2] = r.z;
    }

}

How should I implement the multiplication of this quaternion times the one from the parameters times the conjugate of this quaternion

I know I know close, but I am definitely missing something.

unixsnob
  • 1,685
  • 2
  • 19
  • 45
  • `this.conj();` isn't a thing. And where is `operator*()`? Please post real code. – juanchopanza Jul 16 '15 at 16:04
  • `(*this).operator*() q` are you trying to multiply your 2 class objects here using the operator overloading?? – user007 Jul 16 '15 at 16:05
  • You are showing the `+` operator but you are using the `*` operator. Please **[edit]** your question with an [mcve] or [SSCCE (Short, Self Contained, Correct Example)](http://sscce.org) – NathanOliver Jul 16 '15 at 16:05
  • Also, you're returning a pointer to a local variable: `return double[3] { r.X, r.Y, r.Z };`. – juanchopanza Jul 16 '15 at 16:06
  • And also you're declaring a static operator overload, which is illegal. There's like ten ways in which that code doesn't compile. – Sneftel Jul 16 '15 at 16:07
  • Just a resource why it cannot be static http://stackoverflow.com/questions/11894124/why-overloaded-operators-cannot-be-defined-as-static-members-of-a-class – user007 Jul 16 '15 at 16:10
  • @all, as usual the downvoting + closing brigade contributes to nothing. Got to love stackoverflow. Removed all the static modified. Now if someone can actually say something constructive, that would actually be useful – unixsnob Jul 16 '15 at 16:17
  • @unixsnob Are you trying to do `r = *this * q`? – Sneftel Jul 16 '15 at 16:23
  • @Sneftel: I need to make some changes to the compiler. Basically calculate the Hamilton Product as per the comment in the function in question. – unixsnob Jul 16 '15 at 16:31
  • Not sure why you think you need to make changes to the compiler in order to do that. Knock yourself out, though. – Sneftel Jul 16 '15 at 16:33
  • @Sneftel /s compiler code. – unixsnob Jul 16 '15 at 16:55

1 Answers1

1

So, when you are overloading you operators in your question you write this ::

Quaternion operator*(Quaternion q1, Quaternion q2) Since this is a member function you shall either change it to this

(1) Quaternion operator*(Quaternion q2)

or possibly use a friend function like

(2) friend Quaternion operator*(Quaternion q1, Quaternion q2)

So, when you want to multiply your 2 Quaternion objects and using the declaration as mentioned in (1), possibly like this ::

Quaternion a, b, c;
c = a*b;

Your call a*b get somehow transformed into a.operator*(b) itself so you do not have to explicitly call Quaternion r = a.operator*(b); (like i see in your code) Inside your operator function you can access the members of a using this pointer, since your call to the function operator*() get called on object a.

That is what operator overloading is meant for! we use the normal operators between objects and not call the functions.

While using the (2) declaration, you use a friend, a friend is not a member function, but it can access the private data members, so when you use the declaration (2) you pass 2 arguments, for both the objects involved in the calculation, Since this time the function is not called on any object!

Further you might consider returning a reference of the object from your operator overload function, this will help you achieve associativity like (a+b+c) kind of thing.

Like changing your declaration to this::

Quaternion& operator*(Quaternion q2) or

friend Quaternion& operator*(Quaternion q1, Quaternion q2)

Hope this could help!

Try looking into this :: Operator overloading (It explains everything in detail!)

Community
  • 1
  • 1
user007
  • 2,156
  • 2
  • 20
  • 35
  • you mean making the functions return `Quaternion&` ? – unixsnob Jul 16 '15 at 16:30
  • will give it a try and get back to you. Thanks for actually answering the questions, instead of picking holes in it. I wrote the code on the go from some c#. Hence the pointer errors. – unixsnob Jul 16 '15 at 16:32
  • 1
    Nevermind!! Well changing the return type won't actually take away your compile errors, also consider changing your statement `Quaternion r = (*this).operator*() q;` to `Quaternion r = (*this) * q;` if you are trying to multiply the 2 objects! – user007 Jul 16 '15 at 16:34