returning a multidimensional array

Started by
17 comments, last by Jingo 18 years, 10 months ago
Ok, I'm writing a function that I want to return a rotation matrix. It looks like this: float[3][3] multmat(float x, float y, float z, double theta) { float rm[3][3]; float c = cos(theta); float s = sin(theta); float t = 1 - cos(theta); rm[0][0] = t*x*x + c; rm[1][0] = t*x*y - s*z; rm[2][0] = t*x*z + s*y; rm[0][1] = t*x*y + s*z; rm[1][1] = t*y*y + c; rm[2][1] = t*y*z - s*x; rm[0][2] = t*x*z - s*y; rm[1][2] = t*y*z + s*x; rm[2][2] = t*z*z + c; return rm; } However, C++ doesn't seem to like the float[3][3] return declaration. It says: 38 C:\Dev-Cpp\linedraw.cpp expected unqualified-id before '[' token Any ideas how to get this working? Thanks. Mike C. http://www.coolgroups.com/zoomer/
Mike C.http://www.coolgroups.com/zoomer/http://www.coolgroups.com/ez/
Advertisement
Two mistakes:
1. That memory will be deleted once the function is done, so you might get garbage.
2. You have to always return a pointer when you want to return an array (regardless of how many dimensions it has).
There's two ways to do it...

By returning a pointer to a point, which is what a multi-array is.
float ** foo(){  float array2[3][3];  initalize_array2;  return array2;}...float array[3][3];array = foo;


and by passing by reference, which would automaitically update your array
void foo(float** array){  assign_array(array);}...float array[3][3];foo(array);



A somewhat simple way to do this is to encapsulate the entire thing into a class or a struct.
I would do it like this:

float rm[3][3];float[3][3] multmat(float x, float y, float z, double theta){float c = cos(theta);float s = sin(theta);float t = 1 - cos(theta);rm[0][0] = t*x*x + c;rm[1][0] = t*x*y - s*z;rm[2][0] = t*x*z + s*y;rm[0][1] = t*x*y + s*z;rm[1][1] = t*y*y + c;rm[2][1] = t*y*z - s*x;rm[0][2] = t*x*z - s*y;rm[1][2] = t*y*z + s*x;rm[2][2] = t*z*z + c;}void some_other_function(){//just use rm normally}
What? Isn't that what I had?

Mike C.
http://www.coolgroups.com/zoomer/

Quote:Original post by Raduprv
I would do it like this:

float rm[3][3];float[3][3] multmat(float x, float y, float z, double theta){float c = cos(theta);float s = sin(theta);float t = 1 - cos(theta);rm[0][0] = t*x*x + c;rm[1][0] = t*x*y - s*z;rm[2][0] = t*x*z + s*y;rm[0][1] = t*x*y + s*z;rm[1][1] = t*y*y + c;rm[2][1] = t*y*z - s*x;rm[0][2] = t*x*z - s*y;rm[1][2] = t*y*z + s*x;rm[2][2] = t*z*z + c;}void some_other_function(){//just use rm normally}


Mike C.http://www.coolgroups.com/zoomer/http://www.coolgroups.com/ez/
No, it isn't. Look closer.
[edit] Actually, I forgot to modify the function to return void.
A few things here.
If you're doing 3d rotation, you need a 4x4 array, not a 3x3 array.

If the following prototype doesn't work:

float[3][3] multmat(float x, float y, float z, double theta) {// stuff //}


You should make it like this.

float **BuildRotateMatrix(float axis_x, float axis_y, float axis_z, float theta) {   float **rm;   int i;// the following chunk will allocate ram in a way that will NOT be //// de-allocated when the function returns; //// Of course, it would be MUCH faster and cause less memory fragmentation //// if you allocate all the matrices when the program begins, and do NO //// allocation in these functions at all. //// Just pass in the arrays instead (ie, float **matfunc(float **matrix, other params..) //   // need a 4x4 array for 3d matrix math, or 3x3 array for 2d matrix math //   rm = (float **)malloc(sizeof(float*) * 4);   if(NULL == rm) return NULL; // out of memory //   for(i = 0; i < 4; i++) {       rm = (float *)malloc(sizeof(float) * 4);      if(NULL == rm) return NULL; // you probably want to free up the //                                     // memory allocated in previous calls first //   }   // end memory allocation chunk //   // now, the following code I took almost entirely from your initial post //   // is ROTATION code (like you said), not a matrix multiply.  //   // It would be a good idea to name the function accordingly, otherwise //   // it will be VERY confusing to use. //      float c = fcos(theta); // if you use plain-old cos() or sin() //   float s = fsin(theta); // you are casting from double to float //   float t = 1 - fcos(theta); // which can also be slow //   rm[0][0] = t*x*x + c;   rm[1][0] = t*x*y - s*z;   rm[2][0] = t*x*z + s*y;   rm[3][0] = 0.0f; // new //   rm[0][1] = t*x*y + s*z;   rm[1][1] = t*y*y + c;   rm[2][1] = t*y*z - s*x;   rm[3][1] = 0.0f; // new //   rm[0][2] = t*x*z - s*y;   rm[1][2] = t*y*z + s*x;   rm[2][2] = t*z*z + c;   rm[3][2] = 0.0f; // new //    // new addition //   rm[0][3] = 0.0f;   rm[1][3] = 0.0f;   rm[2][3] = 0.0f;   rm[3][3] = 1.0f;   return rm;}


If you allocate memory in your functions, make sure you deallocate it after
you're done using it, or you'll run out of memory in no time considering
that these functions will be done many times per second.
Again, don't allocate memory in a 3d math function, since you'll have a
metric butt-load of memory fragmentation in no time, and it'll be amazingly
slow (memory allocation is a slow process).

If you use a 3x3 array for 3d math, you should rewrite all your functions
to use 4x4 arrays. Otherwise, nothing will work.
Quote:Original post by Cryoknight
A few things here.
If you're doing 3d rotation, you need a 4x4 array, not a 3x3 array.

If you use a 3x3 array for 3d math, you should rewrite all your functions
to use 4x4 arrays. Otherwise, nothing will work.

That's a bunch of balogna. You can do 3D rotations perfectly fine with a 3x3 matrix.

In response to the original post, either pass the array by reference or return the array encapsulated inside a struct:

void multmat( float (&your_matrix)[3][3], float x, float y, float z, double theta)


-or-

struct blah { float matrix[3][3]; };blah multmat( float x, float y, float z, double theta);
If all you are doing is rotation, sure. But not if you want to be able
to do the full 3d pipeline of matrix multiplications.
If you didn't need the 4x4 matrices, they wouldn't bother using them
in EVERY SINGLE 3d programming book.

This topic is closed to new replies.

Advertisement