M
mast4as
Hi everyone
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 );
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 );