Hi,
I am writing a geometry engine using homogeneous coordinates (4D representing 3D Euclidean coordinates) used for perspective projection. This is handled by two classes a 4-Vector "fourVector" and a 4x4 Matrix "fourMatrix". For speed I have not (yet) separated class and member function declaration from definition.
class fourVector{
public:
float x,y,z,w;
// float w;
// Vector v;
fourVector():x(0),y(0),z(0),w(0){}
// use int variable in argument to limit values
// first constructor converts existing 3vector to corresponding four vector
fourVector(Vector &q, int i):x(q.x),y(q.y),z(q.z){
w=float(i); // convert boolean true/false to a float
}
fourVector(Vector q, int i):x(q.x),y(q.y),z(q.z){
w=float(i); // convert boolean true/false to a float
}
//fourVector(Vector(float x,float y, float z), int i):x(x),y(y),z(z){
// w=float(i);
//}
fourVector(float x, float y, float z, int i): x(x),y(y),z(z){
w=float(i);
}
fourVector(Vector &q, float f):x(q.x),y(q.y),z(q.z),w(f){
}
fourVector operator*(const fourVector &q){
return fourVector(x*q.x,y*q.y,z*q.z,w*q.w);
}
};
class fourMatrix{
public:
fourVector i,j,k,l;
// take four COLUMN 4-vectors i,j,k,l to form 4-Matrix
fourMatrix(fourVector &i, fourVector &j, fourVector &k, fourVector &l): i(i),j(j),k(k),l(l){
}
fourMatrix(fourVector i, fourVector j, fourVector k, fourVector l): i(i),j(j),k(k),l(l){
}
// take rotation 3-matrix m and translation 3-vector q to form homogeneous 4-matrix i.e. pad i.z,j.z,k.z,l.x,l.y,l.z with 0's and set l.w to 1.0
fourMatrix(Matrix &m, Vector &q){
i.x=m.i.x;i.y=m.i.y;i.z=m.i.z;i.w=0.0;
j.x=m.j.x;j.y=m.j.y;j.z=m.j.z;j.w=0.0;
k.x=m.k.x;k.y=m.k.y;k.z=m.k.z;k.w=0.0;
l.x=q.x;l.y=q.y;l.z=q.z;l.w=1.0;
}
// use this constructor for determining projection matrix
fourMatrix(Vector &q){
i=fourVector(1,0,0,0);
j=fourVector(0,1,0,0);
// check whether q.z > 0
if (q.z!=0.0) k=fourVector(0,0,1,1/q.z);
else k=fourVector(0,0,1,INFINITY1);
l=fourVector(-q.x,-q.y,0,0);
/* i.x=1.0;i.y=0.0;i.z=0.0;i.w=0.0;
j.x=0.0;j.y=1.0;j.z=0.0;j.w=0.0;
k.x=0.0;k.y=0.0;k.z=0.0;
if ((q.z!=0.0) > 0) k.z=1/q.z;
else k.z=INFINITY1;
l.x=-q.x;l.y=-q.y;l.z=0.0;l.w=0.0;*/
}
// multiply 4-matrix with 4-vector
fourVector operator*(const fourVector &q)const{
return fourVector(i.x*q.x+j.x*q.y+k.x*q.z+l.x*q.w,i.y*q.x+j.y*q.y+k.y*q.z+l.y*q.w,i.z*q.x+j.z*q.y+k.z*q.z+l.z*q.w,
i.w*q.x+j.w*q.y+k.w*q.z+l.w*q.w);
}
fourMatrix operator* (const fourMatrix &m) const{
// fourVector a,b,c,d;
// fourMatrix n;
fourVector a(i.x*m.i.x+j.x*m.i.y+k.x*m.i.z+l.x*m.i.w, i.y*m.i.x+j.y*m.i.y+k.y*m.i.z+l.y*m.i.w,
i.z*m.i.x+j.z*m.i.y+k.z*m.i.z+l.z*m.i.w, i.w*m.i.x+j.w*m.i.y+k.w*m.i.z+l.w*m.i.w);
fourVector b(i.x*m.j.x+j.x*m.j.y+k.x*m.j.z+l.x*m.j.w, i.y*m.j.x+j.y*m.j.y+k.y*m.j.z+l.y*m.j.w,
i.z*m.j.x+j.z*m.j.y+k.z*m.j.z+l.z*m.j.w, i.w*m.j.x+j.w*m.j.y+k.w*m.j.z+l.w*m.j.w);
fourVector c(i.x*m.k.x+j.x*m.k.y+k.x*m.k.z+l.x*m.k.w, i.y*m.k.x+j.y*m.k.y+k.y*m.k.z+l.y*m.k.w,
i.z*m.k.x+j.z*m.k.y+k.z*m.k.z+l.z*m.k.w, i.w*m.k.x+j.w*m.k.y+k.w*m.k.z+l.w*m.k.w);
fourVector d(i.x*m.l.x+j.x*m.l.y+k.x*m.l.z+l.x*m.l.w, i.y*m.l.x+j.y*m.l.y+k.y*m.l.z+l.y*m.l.w,
i.z*m.l.x+j.z*m.l.y+k.z*m.l.z+l.z*m.l.w, i.w*m.l.x+j.w*m.l.y+k.w*m.l.z+l.w*m.l.w);
fourMatrix n(a,b,c,d);
return n;
}
// this returns a 3-Vector containing projection of points (x,y,0) into MLC coordinates
Vector projection(Vector &e,fourVector &d){
fourVector f;
fourMatrix m(Vector &e);// construct 4-Matrix m from 3-Vector e using special constructor;
// m=(Vector &e);
f=m*d;
if (f.w!=0.0) return Vector(f.x/f.w,f.y/f.w,0);
else return Vector(0,0,0);
}
// as above but with 3-vector e and c and integer i as arguments
Vector projection(Vector &e,Vector &c, int i){
fourVector d(&c,i); // construct fourVector d from 3-Vector c and i;
fourVector f;
fourMatrix m(fourVector &e);// construct 4-Matrix m from 3-Vector e using special constructor
f=m*d;
if (f.w!=0.0) return Vector(f.x/f.w,f.y/f.w,0);
else return Vector(0,0,0);
}
};
Below is the error message
‘fourMatrix fourMatrix::operator*(const fourMatrix&) const’:
/home/mark/Vega_lib/Source/Geom.h:52: error: call of overloaded ‘fourMatrix(fourVector&, fourVector&, fourVector&, fourVector&)’ is ambiguous
/home/mark/Vega_lib/Source/Geom.h:7: note: candidates are: fourMatrix::fourMatrix(fourVector, fourVector, fourVector, fourVector)
/home/mark/Vega_lib/Source/Geom.h:5: note: fourMatrix::fourMatrix(fourVector&, fourVector&, fourVector&, fourVector&)
/home/mark/Vega_lib/Source/Geom.h: In member function ‘Vector fourMatrix::projection(Vector&, fourVector&)’:
/home/mark/Vega_lib/Source/Geom.h:71: error: no match for ‘operator*’ in ‘m * d’
/home/mark/Vega_lib/Source/Geom.h: In member function ‘Vector fourMatrix::projection(Vector&, Vector&, int)’:
/home/mark/Vega_lib/Source/Geom.h:77: error: no matching function for call to ‘fourVector::fourVector(Vector*, int&)’
/home/mark/Vega_lib/Source/Geom.h:21: note: candidates are: fourVector::fourVector(Vector&, float)
/home/mark/Vega_lib/Source/Geom.h:18: note: fourVector::fourVector(float, float, float, int)
/home/mark/Vega_lib/Source/Geom.h:12: note: fourVector::fourVector(Vector, int)
/home/mark/Vega_lib/Source/Geom.h:9: note: fourVector::fourVector(Vector&, int)
/home/mark/Vega_lib/Source/Geom.h:6: note: fourVector::fourVector()
/home/mark/Vega_lib/Source/Geom.h:1: note: fourVector::fourVector(const fourVector&)
/home/mark/Vega_lib/Source/Geom.h:80: error: no match for ‘operator*’ in ‘m * d’
My problem occurs with the
fourMatrix operator*
. This multiplies 2 two 4x4 matrices and (should) return the result, by first calculating the four column 4-Vectors (a,b,c,d) which form the final (product) 4-Matrix as an intermediate step (for clarity). In particular the line
fourMatrix n(a,b,c,d);
line 45 in fourMatrix extract. I should point out that I am still a rather inexperienced C++ programmer, but I am trying... (and this is not for an assignment, it is a real problem that I'm trying to solve)
Alternatively does anyone know of open source code/libraries (C++ ideally) that will do perspective projection with homogeneous coordinates to prevent further headaches and grey-hairs!
Thanks for taking the time to read this and in particular to any that may respond