[Classes] It isn't easy to have a function return an array as a value; you'd need to allocate the space for the array. It's easier to use classes.
Some class declarations are suggested below. To keep things
easy, let's use a vector class vec3
and a matrix class
mat33
for three dimensions only, which means that memory
allocation issues can be avoided entirely.
With a class, you can still define []
so the result looks like
an array: R[i][j]
and so on. You can also define *
for
matrices times matrices and vectors times matrices so that you
can write R = A*B
for matrices.
Suggested classes, in outline:
class vec3
{
double ent[3]; // entries
friend ostream& operator<<(ostream&, const vec3&);
public:
vec3(); // (set entries to 0)
vec3(double a, double b, double c){ ent[0]=a; ent[1]=b; ent[2]=c; }
vec3( const vec3& v ); // copy constructor
// no destructor necessary
vec3& operator=( const vec3& v ); // assignment
double& operator[](int i); // so can say v[i] = 3, etc.
}; // (be sure to check 0 <= i < 3)
ostream& operator<<(ostream& o, const vec3& v);
class mat33
{
vec3 rows[3];
friend ostream& operator<<(ostream&, mat33&);
public:
mat33(){} // (entries will already be 0)
mat33( const mat33& m ); // copy constructor
// no destructor necessary
mat33& operator=(const mat33& m); // assignment
vec3& operator[](int i); // so m[i] means a row, m[i][j] an entry
mat33 operator*(const mat33& m); // returns this mat times m
mat33 transpose(); // returns transpose of this mat
};
mat33 identity33();
mat33 rot3(double theta, int i_from, int i_to);
vec3 operator*(const vec3& v, const mat33& m);
vec3 cartesian(double latitude, double longitude); // (can use prev fns)
ostream& operator<<(ostream& o, const mat33& m);
Of course, you will need to supply expansions for functions, either in-line or separately.
Be sure to include any headers needed.
Technically, in the classes above, whenever a method does not
change any class member it is best to tag it with const
, as
in mat33 transpose() const;
Here are expansions of the identity()
and rot3
functions--but
let's use the name identity33()
instead.
mat33 identity33()
{
mat33 M; // entries start out 0
for (int i=0; i<3; i++)
M[i][i] = 1.0;
return M;
}
mat33 rot3(double theta, int i_from, int i_to)
{
mat33 M = identity33();
M[i_from][i_from] = cos(theta);
M[i_to][i_to] = cos(theta);
M[i_from][i_to] = sin(theta);
M[i_to][i_from] = -sin(theta);
return M; // don't forget this line!
}
In writing the rot3
function, to keep things straight just
focus on the case where i_from
is 0 (x
) and i_to
is 1
(y
). Notice that the rot3
function works correctly no
matter whether you want rot3(theta,x,y)
or rot3(theta,y,x)
.
Assuming you have also included the matrix multiplication routine
as a member function of mat33
, namely
mat33 operator*(mat33 m)
or better,
mat33 operator*(const mat33& m)
, you can now say simply
mat33 R = rot3(view_long_rad + pi/2,y,x) * rot3(pi/2 - view_lat_rad,z,y);