Velocity Reviews > C++ > vector functions

vector functions

Michael Sgier
Guest
Posts: n/a

 09-27-2005
Hello
If someone could explain the code below to me would be great.

// return angle between two vectors
const float inline Angle(const CVector& normal) const
{
return acosf(*this % normal);
}

// reflect this vector off surface with normal vector
const CVector inline Reflection(const CVector& normal) const
{
const CVector vec(*this | 1); // normalize this vector
return (vec - normal * 2.0 * (vec % normal)) * !*this;
}

// rotate angle degrees about a normal
const CVector inline Rotate(const float angle, const CVector& normal) const
{
const float cosine = cosf(angle);
const float sine = sinf(angle);

return CVector(*this * cosine + ((normal * *this) * (1.0f - cosine)) *
normal + (*this ^ normal) * sine);
}

This is producing the following errors:

vector.h:220: error: declaration does not declare anything
vector.h:220: error: syntax error before `inline'
vector.h:226: error: ISO C++ forbids defining types within return type
vector.h:226: error: syntax error before `inline'
vector.h:233: error: syntax error before `inline'
vector.h:236: error: `angle' was not declared in this scope
vector.h:238: error: syntax error before `return'

What do % and ^ produce? Why is there a const also at the end of the
function definition?
THANKS and regards
Michael

Christian Meier
Guest
Posts: n/a

 09-27-2005
"Michael Sgier" <(E-Mail Removed)> schrieb im Newsbeitrag
news:43396eaa\$0\$1150\$(E-Mail Removed)...
> Hello
> If someone could explain the code below to me would be great.
>
> // return angle between two vectors
> const float inline Angle(const CVector& normal) const
> {
> return acosf(*this % normal);
> }
>
> // reflect this vector off surface with normal vector
> const CVector inline Reflection(const CVector& normal) const
> {
> const CVector vec(*this | 1); // normalize this vector
> return (vec - normal * 2.0 * (vec % normal)) * !*this;
> }
>
> // rotate angle degrees about a normal
> const CVector inline Rotate(const float angle, const CVector& normal)

const
> {
> const float cosine = cosf(angle);
> const float sine = sinf(angle);
>
> return CVector(*this * cosine + ((normal * *this) * (1.0f - cosine)) *
> normal + (*this ^ normal) * sine);
> }
>
> This is producing the following errors:
>
> vector.h:220: error: declaration does not declare anything
> vector.h:220: error: syntax error before `inline'
> vector.h:226: error: ISO C++ forbids defining types within return type
> vector.h:226: error: syntax error before `inline'
> vector.h:233: error: syntax error before `inline'
> vector.h:236: error: `angle' was not declared in this scope
> vector.h:238: error: syntax error before `return'

Paste your whole class. Or better: Reduce your code as much as possible and

> What do % and ^ produce?

% is the modulus operator. It returns the remainder of a division.
^ is the bitwise-exclusive-or operator. It compares each bit. If one of them
is 0 and the other one is 1, the corresponding bit in the result is also 1,
otherwise it is 0.

> Why is there a const also at the end of the
> function definition?

Functions of a class are not allowed to modify the member variables if a
function was declared as const.

> THANKS and regards
> Michael

Greetings Chris

Kai-Uwe Bux
Guest
Posts: n/a

 09-27-2005
Christian Meier wrote:

> "Michael Sgier" <(E-Mail Removed)> schrieb im Newsbeitrag
> news:43396eaa\$0\$1150\$(E-Mail Removed)...
>> Hello
>> If someone could explain the code below to me would be great.
>>
>> // return angle between two vectors
>> const float inline Angle(const CVector& normal) const
>> {
>> return acosf(*this % normal);
>> }
>>
>> // reflect this vector off surface with normal vector
>> const CVector inline Reflection(const CVector& normal) const
>> {
>> const CVector vec(*this | 1); // normalize this vector
>> return (vec - normal * 2.0 * (vec % normal)) * !*this;
>> }
>>
>> // rotate angle degrees about a normal
>> const CVector inline Rotate(const float angle, const CVector& normal)

> const
>> {
>> const float cosine = cosf(angle);
>> const float sine = sinf(angle);
>>
>> return CVector(*this * cosine + ((normal * *this) * (1.0f - cosine)) *
>> normal + (*this ^ normal) * sine);
>> }
>>
>> This is producing the following errors:
>>
>> vector.h:220: error: declaration does not declare anything
>> vector.h:220: error: syntax error before `inline'
>> vector.h:226: error: ISO C++ forbids defining types within return type
>> vector.h:226: error: syntax error before `inline'
>> vector.h:233: error: syntax error before `inline'
>> vector.h:236: error: `angle' was not declared in this scope
>> vector.h:238: error: syntax error before `return'

>
> Paste your whole class. Or better: Reduce your code as much as possible
> and then paste your class here.
>
>> What do % and ^ produce?

>
> % is the modulus operator. It returns the remainder of a division.
> ^ is the bitwise-exclusive-or operator. It compares each bit. If one of
> them is 0 and the other one is 1, the corresponding bit in the result is
> also 1, otherwise it is 0.

Well, I am inclined to bet that these operators are overloaded in that
vector class to compute the scalar product and the cross product, and I
also suspect that operator! has been tweaked to compute the norm of the
vector and that operator| rescales a vector to a given length.

Best

Kai-Uwe Bux

persenaama
Guest
Posts: n/a

 09-27-2005
/*
const float inline Angle(const CVector& normal) const
{
return acosf(*this % normal);
}
*/

Above the % should be scalar product so that the angle between *this
and normal would be computed, it's generally a bad to use % for cross
product, which it is often seen used in code like this. Using it for
dot/scalar product is even more strange.

Just commenting on that oddity, I could comment on the errors if I knew
which line was which (eg. which error correspond to which line). I bet
somewhere along the line some declaration was missed (maybe the headers
are not self-contained or require specific order of inclusion,
whatever, beats me w/o seeing more of the code..

persenaama
Guest
Posts: n/a

 09-27-2005
I just cannot resisting replying again.. I keep staring at the code in
disbelief: really bizarre use of operator overloading. +, -, /, * ..
are are still cool and useful since the meaning is easily understood,
but... what is happening here is beyond belief.. incredible stuff.. no
offence! 8P

Richard Herring
Guest
Posts: n/a

 09-27-2005
In message <dhbrdr\$17m\$(E-Mail Removed)>, Christian Meier
<(E-Mail Removed)> writes
>"Michael Sgier" <(E-Mail Removed)> schrieb im Newsbeitrag
>news:43396eaa\$0\$1150\$(E-Mail Removed).. .
>> Hello
>> If someone could explain the code below to me would be great.
>>
>> // return angle between two vectors
>> const float inline Angle(const CVector& normal) const
>> {
>> return acosf(*this % normal);
>> }
>>

This appears to be a member function. So what's the declaration of the
class of which it's a member? We're not mind-readers here.

>> // reflect this vector off surface with normal vector
>> const CVector inline Reflection(const CVector& normal) const
>> {
>> const CVector vec(*this | 1); // normalize this vector
>> return (vec - normal * 2.0 * (vec % normal)) * !*this;
>> }
>>
>> // rotate angle degrees about a normal
>> const CVector inline Rotate(const float angle, const CVector& normal)

>const
>> {
>> const float cosine = cosf(angle);
>> const float sine = sinf(angle);
>>
>> return CVector(*this * cosine + ((normal * *this) * (1.0f - cosine)) *
>> normal + (*this ^ normal) * sine);
>> }
>>
>> This is producing the following errors:
>>
>> vector.h:220: error: declaration does not declare anything

So which of the above is line 220? We're not mind-readers here.

>> vector.h:220: error: syntax error before `inline'
>> vector.h:226: error: ISO C++ forbids defining types within return type
>> vector.h:226: error: syntax error before `inline'
>> vector.h:233: error: syntax error before `inline'
>> vector.h:236: error: `angle' was not declared in this scope
>> vector.h:238: error: syntax error before `return'

>
>Paste your whole class. Or better: Reduce your code as much as possible and
>
>> What do % and ^ produce?

>
>% is the modulus operator. It returns the remainder of a division.
>^ is the bitwise-exclusive-or operator. It compares each bit. If one of them
>is 0 and the other one is 1, the corresponding bit in the result is also 1,
>otherwise it is 0.

Not quite. % and ^ applied to built-in types do as you say. Here the
operands are of type CVector, whatever that is. My guess is that the
author of the class CVector has overloaded those operators (and also
operator| and operator*) to make them perform some completely unrelated
function.

Which is, of course, *EVIL*.

>
>> Why is there a const also at the end of the
>> function definition?

>
>Functions of a class are not allowed to modify the member variables if a
>function was declared as const.
>

--
Richard Herring

Kai-Uwe Bux
Guest
Posts: n/a

 09-28-2005
Richard Herring wrote:

> In message <dhbrdr\$17m\$(E-Mail Removed)>, Christian Meier
> <(E-Mail Removed)> writes
>>"Michael Sgier" <(E-Mail Removed)> schrieb im Newsbeitrag
>>news:43396eaa\$0\$1150\$(E-Mail Removed). ..

[snip]
>>> // reflect this vector off surface with normal vector
>>> const CVector inline Reflection(const CVector& normal) const
>>> {
>>> const CVector vec(*this | 1); // normalize this vector
>>> return (vec - normal * 2.0 * (vec % normal)) * !*this;
>>> }
>>>
>>> // rotate angle degrees about a normal
>>> const CVector inline Rotate(const float angle, const CVector& normal)

>>const
>>> {
>>> const float cosine = cosf(angle);
>>> const float sine = sinf(angle);
>>>
>>> return CVector(*this * cosine + ((normal * *this) * (1.0f - cosine)) *
>>> normal + (*this ^ normal) * sine);
>>> }

[snip]
>>% is the modulus operator. It returns the remainder of a division.
>>^ is the bitwise-exclusive-or operator. It compares each bit. If one of
>>them is 0 and the other one is 1, the corresponding bit in the result is
>>also 1, otherwise it is 0.

>
> Not quite. % and ^ applied to built-in types do as you say. Here the
> operands are of type CVector, whatever that is. My guess is that the
> author of the class CVector has overloaded those operators (and also
> operator| and operator*) to make them perform some completely unrelated
> function.
>
> Which is, of course, *EVIL*.

I beg to differ. It is not evil; it is the legitimate attempt to make the
math in your code resemble the math from your text book as closely as
possible. This, makes it indeed easier to maintain the code (after some
learning curve). The fact that one can actually guess what the operators in
the OPs code are doing supports this hypothesis:

CVector operator| ( double length ) const;
// rescale a vector to length

double operator% ( CVector const & other ) const;
// scalar product

double operator! ( void ) const;
// norm

CVector operator^ ( CVector const & other ) const;
// cross product

[operator* appears to denote a projection, and I have to admit that the use
of an operator for this is questionable as you usually will not find infix
notation for projections in math texts.]

Whether operator overloading is moral or evil is a cultural question, and
C++ allows you to implement special purpose sublanguages. Admittedly, this
is a double edged sword. In the context of math programming, I find it by

Best

Kai-Uwe Bux

Christian Meier
Guest
Posts: n/a

 09-28-2005
"Kai-Uwe Bux" <(E-Mail Removed)> schrieb im Newsbeitrag
news:dhbupe\$mmi\$(E-Mail Removed)...
> Christian Meier wrote:
>
> > "Michael Sgier" <(E-Mail Removed)> schrieb im Newsbeitrag
> > news:43396eaa\$0\$1150\$(E-Mail Removed)...
> >> Hello
> >> If someone could explain the code below to me would be great.
> >>
> >> // return angle between two vectors
> >> const float inline Angle(const CVector& normal) const
> >> {
> >> return acosf(*this % normal);
> >> }
> >>
> >> // reflect this vector off surface with normal vector
> >> const CVector inline Reflection(const CVector& normal) const
> >> {
> >> const CVector vec(*this | 1); // normalize this vector
> >> return (vec - normal * 2.0 * (vec % normal)) * !*this;
> >> }
> >>
> >> // rotate angle degrees about a normal
> >> const CVector inline Rotate(const float angle, const CVector& normal)

> > const
> >> {
> >> const float cosine = cosf(angle);
> >> const float sine = sinf(angle);
> >>
> >> return CVector(*this * cosine + ((normal * *this) * (1.0f - cosine)) *
> >> normal + (*this ^ normal) * sine);
> >> }
> >>
> >> This is producing the following errors:
> >>
> >> vector.h:220: error: declaration does not declare anything
> >> vector.h:220: error: syntax error before `inline'
> >> vector.h:226: error: ISO C++ forbids defining types within return type
> >> vector.h:226: error: syntax error before `inline'
> >> vector.h:233: error: syntax error before `inline'
> >> vector.h:236: error: `angle' was not declared in this scope
> >> vector.h:238: error: syntax error before `return'

> >
> > Paste your whole class. Or better: Reduce your code as much as possible
> > and then paste your class here.
> >
> >> What do % and ^ produce?

> >
> > % is the modulus operator. It returns the remainder of a division.
> > ^ is the bitwise-exclusive-or operator. It compares each bit. If one of
> > them is 0 and the other one is 1, the corresponding bit in the result is
> > also 1, otherwise it is 0.

>
> Well, I am inclined to bet that these operators are overloaded in that
> vector class to compute the scalar product and the cross product, and I
> also suspect that operator! has been tweaked to compute the norm of the
> vector and that operator| rescales a vector to a given length.

Of course they are overloaded. Well not "of course", but I am quite sure,
too. Fact is, we do not have any code. Another fact is, that the source
above does not compile.
So, without more code and without guesses the operators want to do, what I
described.
If he wants to know what does operator do with *this, he has to paste more
code of the class, as I mentioned. OK, where do we know if this code is
inside a class? The keyword inline is a bit confusing. It would not be
necessary if this were a class....

Anyway, to be sure, we need more code.

>
>
> Best
>
> Kai-Uwe Bux

Greetings Chris

Michael Sgier
Guest
Posts: n/a

 09-28-2005
Hello again
here's more code with the copyright. I've cutted out the parts that
i've believed to have understood. I would be very grateful for any
explanations on the following especially where i marked my questions.
( and of course the resolving of the errors. The error messages were put
to the corresponding line where
they appeared to the end of the code. )
THANKS and regards
Michael

#ifndef __VECTOR_H
#define __VECTOR_H

#include <math.h>

/*
VECTOR.H

CVector class

Some operators of the CVector class based on
operators of the CVector class by Bas Kuenen.
*/

#define PI (3.14159265359f)

typedef float scalar_t;

class CVector
{
public:
scalar_t x;
scalar_t y;
scalar_t z; // x,y,z coordinates

public:
CVector(scalar_t a = 0, scalar_t b = 0, scalar_t c = 0) : x(a),
y(b), z(c) {} // what does the : here?
CVector(const CVector &vec) : x(vec.x), y(vec.y), z(vec.z) {}

// vector index
scalar_t &operator[](const long idx)
{
return *((&x)+idx);
}

// vector assignment
const CVector &operator=(const CVector &vec) // I don't really
understand: (const CVector &vec) ???
{
x = vec.x;
y = vec.y;
z = vec.z;

return *this;
}

const CVector operator+(const CVector &vec) const
{
return CVector(x + vec.x, y + vec.y, z + vec.z);
}

// vector add (opposite of negation)
const CVector operator+() const // hmmmm???? same to
the following ones
{
return CVector(*this);
}

// scalar self-divecide
const CVector &operator/=(const scalar_t &s)
{
const float recip = 1/s; // for speed, one divecision

x *= recip;
y *= recip;
z *= recip;

return *this;
}

// pre multiply by scalar
friend inline const CVector operator*(const scalar_t &s, const
CVector &vec)
{
return vec*s;
}

const CVector operator*(const CVector& vec) const
{
return CVector(x*vec.x, y*vec.y, z*vec.z);
}

// post multiply by scalar
/*friend inline const CVector operator*(const CVector &vec, const
scalar_t &s)
{
return CVector(vec.x*s, vec.y*s, vec.z*s);
}*/

// divide by scalar
const CVector operator/(scalar_t s) const
{
s = 1/s;

return CVector(s*x, s*y, s*z);
}

// dot product
const scalar_t DotProduct(const CVector &vec) const
{
return x*vec.x + y*vec.x + z*vec.z;
}

// dot product
const scalar_t operator%(const CVector &vec) const // why two
functions?
{
return x*vec.x + y*vec.x + z*vec.z;
}

// normalize this vector
void Normalize()
{
(*this) /= Length(); //humm???
}

const scalar_t operator!() const // why "const
CVector &vec" was omitted?
{
return sqrtf(x*x + y*y + z*z);
}

// return vector with specified length
const CVector operator | (const scalar_t length) const
{
return *this * (length / !(*this));
}

// set length of vector equal to length
const CVector& operator |= (const float length)
{
return *this = *this | length; // what's the
| here?
}

// return angle between two vectors
//those errors here at next line
//vector.h:220: error: declaration does not declare anything
//vector.h:220: error: syntax error before `inline'
const float inline Angle(const CVector& normal) const
{
return acosf(*this % normal);
}

// reflect this vector off surface with normal vector
//those errors here at next line
//vector.h:226: error: ISO C++ forbids defining types within return type
//vector.h:226: error: syntax error before `inline'

const CVector inline Reflection(const CVector& normal) const
{
const CVector vec(*this | 1); // normalize this vector
return (vec - normal * 2.0 * (vec % normal)) * !*this;
}

// rotate angle degrees about a normal
//those errors here at next line
//vector.h:233: error: syntax error before `inline'
const CVector inline Rotate(const float angle, const CVector& normal) const
{
const float cosine = cosf(angle);
//those errors here at next line
//vector.h:236: error: `angle' was not declared in this scope
const float sine = sinf(angle);
//those errors here at next line
//vector.h:238: error: syntax error before `return'
return CVector(*this * cosine + ((normal * *this) * (1.0f - cosine)) *
normal + (*this ^ normal) * sine);
}
};

#endif

John Harrison
Guest
Posts: n/a

 09-28-2005
Michael Sgier wrote:
> Hello again
> here's more code with the copyright. I've cutted out the parts that
> i've believed to have understood. I would be very grateful for any
> explanations on the following especially where i marked my questions.
> ( and of course the resolving of the errors. The error messages were put
> to the corresponding line where
> they appeared to the end of the code. )

> THANKS and regards
> Michael
>
>
> #ifndef __VECTOR_H
> #define __VECTOR_H
>
> #include <math.h>
>
> /*
> VECTOR.H
>
> CVector class
>
> Some operators of the CVector class based on
> operators of the CVector class by Bas Kuenen.
> */
>
> #define PI (3.14159265359f)
>
> typedef float scalar_t;
>
> class CVector
> {
> public:
> scalar_t x;
> scalar_t y;
> scalar_t z; // x,y,z coordinates
>
> public:
> CVector(scalar_t a = 0, scalar_t b = 0, scalar_t c = 0) : x(a),
> y(b), z(c) {} // what does the : here?
> CVector(const CVector &vec) : x(vec.x), y(vec.y), z(vec.z) {}
>
> // vector index
> scalar_t &operator[](const long idx)
> {
> return *((&x)+idx);
> }
>
> // vector assignment
> const CVector &operator=(const CVector &vec) // I don't really
> understand: (const CVector &vec) ???

This is standard. It says that the assignment operator for CVectors
takes one argument by reference (& means by reference), and does not use
that reference to alter the argument (that's what const means). This is
what you would want from an assignment operator. Also notice that the
copy constructor above is similar for similar reasons.

> {
> x = vec.x;
> y = vec.y;
> z = vec.z;
>
> return *this;
> }
>
> const CVector operator+(const CVector &vec) const
> {
> return CVector(x + vec.x, y + vec.y, z + vec.z);
> }
>
> // vector add (opposite of negation)
> const CVector operator+() const // hmmmm???? same to
> the following ones

What's to hmmm? Again we have a const member function returning a const
object. The member function is const because it does not alter the
object. The return is const because if it were not then this code

CVector v1, v2;
+v1 = v2;

would be legal. It's not a big issue because you would probably never
write code like that, but I'm sure you agree there no harm in
disallowing code like that.

> {
> return CVector(*this);
> }
>
>
> // scalar self-divecide
> const CVector &operator/=(const scalar_t &s)
> {
> const float recip = 1/s; // for speed, one divecision
>
> x *= recip;
> y *= recip;
> z *= recip;
>
> return *this;
> }
>
> // pre multiply by scalar
> friend inline const CVector operator*(const scalar_t &s, const
> CVector &vec)
> {
> return vec*s;
> }
>
> const CVector operator*(const CVector& vec) const
> {
> return CVector(x*vec.x, y*vec.y, z*vec.z);
> }
>
> // post multiply by scalar
> /*friend inline const CVector operator*(const CVector &vec, const
> scalar_t &s)
> {
> return CVector(vec.x*s, vec.y*s, vec.z*s);
> }*/
>
> // divide by scalar
> const CVector operator/(scalar_t s) const
> {
> s = 1/s;
>
> return CVector(s*x, s*y, s*z);
> }
>
> // dot product
> const scalar_t DotProduct(const CVector &vec) const
> {
> return x*vec.x + y*vec.x + z*vec.z;
> }
>
> // dot product
> const scalar_t operator%(const CVector &vec) const // why two
> functions?
> {
> return x*vec.x + y*vec.x + z*vec.z;
> }

Good question. Drop the operator% would be my advice.

>
> // normalize this vector
> void Normalize()
> {
> (*this) /= Length(); //humm???
> }

Seems reasonable to me, divide a vector by it's length, resulting is a
vector of length 1. What's the problem?

>
> const scalar_t operator!() const // why "const
> CVector &vec" was omitted?
> {
> return sqrtf(x*x + y*y + z*z);
> }

Because operator! operates on a single CVector, not two CVector's.

>
> // return vector with specified length
> const CVector operator | (const scalar_t length) const
> {
> return *this * (length / !(*this));
> }
>
> // set length of vector equal to length
> const CVector& operator |= (const float length)
> {
> return *this = *this | length; // what's the |
> here?
> }

It calls the function declared immediately above this one. The one with
the comment 'return vector with specified length'.

In general if you define operator@ you should also define operator @=,
this is what is being done here. operator| is defined then operator|= is
defined so that is calls operator|.

>
> // return angle between two vectors
> //those errors here at next line
> //vector.h:220: error: declaration does not declare anything
> //vector.h:220: error: syntax error before `inline'
> const float inline Angle(const CVector& normal) const
> {
> return acosf(*this % normal);
> }

inline is illegal here, remove it. Should be fine then.

>
> // reflect this vector off surface with normal vector
> //those errors here at next line
> //vector.h:226: error: ISO C++ forbids defining types within return type
> //vector.h:226: error: syntax error before `inline'
>
> const CVector inline Reflection(const CVector& normal) const

Ditto.

> {
> const CVector vec(*this | 1); // normalize this vector
> return (vec - normal * 2.0 * (vec % normal)) * !*this;
> }
>
> // rotate angle degrees about a normal
> //those errors here at next line
> //vector.h:233: error: syntax error before `inline'
> const CVector inline Rotate(const float angle, const CVector&
> normal) const

Ditto.

> {
> const float cosine = cosf(angle);
> //those errors here at next line
> //vector.h:236: error: `angle' was not declared in this scope
> const float sine = sinf(angle);
> //those errors here at next line
> //vector.h:238: error: syntax error before `return'
> return CVector(*this * cosine + ((normal * *this) * (1.0f -
> cosine)) *
> normal + (*this ^ normal) * sine);
> }
> };
>
> #endif

john