M

#### mast4as

I have 2 problems related to the same code: one is compile problem

which I am not to sure to solve and the other one is to figure out a

better solution to get cleaner more elegant code. I have 2 classes

normal3 and vector3 which are in essence almost identical. The reason

why I separate them is because in CG they are not transformed the

same. Anyway this is not C++ related... But it's important to separate

them anyway. Now Vector3 and Nomal3 are in essence vector so I shall

be able to do things with them such as dot or cross product or

normalizing them. Because I wasn't able to come up with a better way I

first created 2 classes and then wrote 2 functions for the cross

products which both take 2 vector3 as parameters. But one returns a

vector and the other returns a normal. But when I try to compile ...

the compiler stops on this code (full code at the bottom of the post):

Vector3f edge1 = vert1 - vert0;

Vector3f edge2 = vert2 - vert0;

Vector3f pvec = cross( dir, edge2 );

It doesn't make sense to me because it was quite clear in that case

that cross should return a vector since the object on the left of the

equal sign is a vector ? So why does it say:

xxxx.cppp: In function ‘int xxxxx(const Point3f&, const Vector3f&,

const Point3f&, const Point3f&, const Point3f&, float&, float&,

float&)’:

xxxxx.cpp:277: error: call of overloaded ‘cross(const Vector3<float>&,

Vector3f&)’ is ambiguous

So my first question is how can I remove this error ? (and it would be

great if I could understand what I am doing wrong). Could be that I

use templated classes ?

//////////////

The second question is more a C++ design/architecture one. And it

would be fantastic is anyone could tell me what's the best way of

solving this problem in C++. This seems out of the scope of my

comprehension right now but would really love to progress on this and

come up with a better solution:

As I said in the beginning Vector and Normal share almost all the same

code. The difference is how they are transformed by matrices. So I

don't mind creating two classes for them but what bugs me is that I

have to duplicate all the code... So what I would like to do is to

come with a solution where I can write the code for functions such as

cross, normalize and dot only once and then later do things such as:

Normal3f N = cross( Vector3f( 1, 0 , 0 ), Vector3f( 0, 1, 0 ) );

I don't care if the the result of the cross function which could be a

vector3f is converted to a normal3f type but it doesn't seem to be

able to do this automatically. In other words I guess, I am trying to

find way of making them assignable even though they don't have the

same type. I know it's like going the basic principle of how C++ work

but I am sure there's something clever:

Normal3f n = Vector3f( 10 );

Vector3f vv = Normal( 1.5 );

Normal3d n1 = normalize( vv );

Vector3f vv1 = normalize( n );

It would be great if someone could share his/here experience with me

on this topic as well. Thanks so much for your help

-coralie

Code

template<typename T>

class Vector3

{

public:

Vector3() : x(T(0)), y(T(0)), z(T(0)) {}

Vector3( T xx ) : x(xx), y(xx), z(xx) {}

Vector3( T xx, T yy, T zz ) : x(xx), y(yy), z(zz) {}

friend std:stream & operator << ( std:stream &os, const

Vector3<T> &v )

{

os << v.x << ", " << v.y << ", " << v.z;

return os;

}

T x, y, z;

};

template<typename T>

class Point3

{

public:

Point3() : x(T(0)), y(T(0)), z(T(0)) {}

Point3( T xx ) : x(xx), y(xx), z(xx) {}

Point3( T xx, T yy, T zz ) : x(xx), y(yy), z(zz) {}

Vector3<T> operator - ( const Point3 &p ) const

{ return Vector3<T>( x - p.x, y - p.y, z - p.z ); }

friend std:stream & operator << ( std:stream &os, const Point3<T>

&pt )

{

os << pt.x << ", " << pt.y << ", " << pt.z;

return os;

}

//Vector3<T> operator - ( const Point3<T> &p ) const

//{

// return Vector3<T>( x - p.x, y - p.y, z - p.z );

//}

T x, y, z;

};

template<typename T>

class Normal3

{

public:

Normal3() : x(T(0)), y(T(0)), z(T(0)) {}

Normal3( T xx ) : x(xx), y(xx), z(xx) {}

Normal3( T xx, T yy, T zz ) : x(xx), y(yy), z(zz) {}

friend std:stream & operator << ( std:stream &os, const

Normal3<T> &n )

{

os << n.x << ", " << n.y << ", " << n.z;

return os;

}

T x, y, z;

};

template<typename T>

void normalize( Vector3<T> &v )

{

T len2 = v.x * v.x + v.y * v.y + v.z * v.z;

if ( len2 > 0 ) {

T invLen = 1 / sqrt( len2 );

v.x *= invLen, v.y *= invLen, v.z *= invLen;

}

}

template<typename T>

Vector3<T> cross( const Vector3<T> &va, const Vector3<T> &vb )

{

return Vector3<T>(

va.y * vb.z - va.z * vb.y,

va.z * vb.x - va.x * vb.z,

va.x * vb.y - va.y * vb.x );

}

template<typename T>

Normal3<T> cross( const Vector3<T> &va, const Vector3<T> &vb )

{

return Normal3<T>(

va.y * vb.z - va.z * vb.y,

va.z * vb.x - va.x * vb.z,

va.x * vb.y - va.y * vb.x );

}

//// COMPLAINS

Vector3f edge1 = vert1 - vert0;

Vector3f edge2 = vert2 - vert0;

Vector3f pvec = cross( dir, edge2 );