I have forgotten
my Password

Or login with:

  • Facebookhttp://facebook.com/
  • Googlehttps://www.google.com/accounts/o8/id
  • Yahoohttps://me.yahoo.com
Index » Programming » C/C++ »

3D Rotational Matrix

El_Chunchito\′s Photo
9 Nov 05, 2:09PM
(8 replies)
3D Rotational Matrix
:( Hey, I was wondering if u could show me how to write a 3D rotation matrix function in C++ because I can only find examples in C or OpenGL. Please!! Thanx
oddian\′s Photo
9 Nov 05, 10:05PM
An example in C should be quite easy to modify into C++, what specific troubles are you having at the moment?
El_Chunchito\′s Photo
10 Nov 05, 1:59AM
The thing is, I want to create a sphere using polygon meshing, I got told that if I understood how 3D matrices worked, I should be fine. I understand the whole concept of them and how they are applied to 3D graphics but, I am having troubles using them.........
lucian\′s Photo
10 Nov 05, 8:41AM
Hi there!

So you know how a 3D rotation matrix can be expressed in mathematical form. All you need to do is write a function that applies this transformation to a certain point in 3D given by its coordinates. I would consider storing the point as a struct or as an array of 3 components, i.e.

struct Point
{
  double x, y, z;
};

or

double Point[3];

The function prototype would then have this form:

Point Rotate(Point &P, double alpha, double beta, double gamma);

if you would like not to modify the original point and obtain another, by rotation, or

void Rotate(Point &P, double alpha, double beta, double gamma);

which would rotate the point and affect its coordinates, without creating a second point. In both versions I have considered alpha, beta and gamma to be the angles about the X, Y and Z axis. In what implementation of this function is concerned, it is easy to construct the 3D rotation matrix by first calculating sin(alpha), cos(alpha), sin(beta), cos(beta), sin(gamma), cos(gamma), storing them in separate variables, and then calculate each element of the matrix. To apply the rotation on the given point you would consider that the point forms a matrix of 3 rows and 1 column, with its elements coresponding to the 3 coordinates. Then you would do matrix multiplication between this row-matrix and the rotation matrix, which I assume would not be very difficult to do. In the end, return the new point if you have considered the first version of the prototype.

I hope this helps.

john\′s Photo
10 Nov 05, 8:59AM
Do you want to use Polygons or just triangles?

If you really want to go completely C++, then I'd start with something like this:

class Point
{
  int x,y,z;
  void rotate(alpha_x, alpha_y, alpha_z);
  void scale(scale_x, scale_y, scale_z);  
}

where rotate and scale are the first of a collection of functions you'll probably want to manipulate each point. rotate for example, would translate any point around a central point (e.g. x=y=z=0), using the classical matrix transformation, i.e to rotate about x-axis you want: To rotate about the y_axis you want: Then for the z-axis:

At this point you can go two ways: a) Define a single array of Point, which contains the nodes of your entire mesh for the sphere (the option I'd do). Then have a new class relating the interconnectivity between nodes - Pro: Faster; Con: Not tightly encapsulated. b) Define a class that handles each polygon separately - Con: a little memory inefficient.

Thus

class TriNodes
{
  int m_points[3];  // you put in here the index values for each Point
}

You then have something like:

class Sphere
{
  std::vector<Point> m_points;
  std::vector<TriNodes> m_nodes;
 
  // with functions
  void addNode(int x, y, z);   
  void addTriMesh(int a, int b, int c); // where a,b,c reference m_points[a], m_points[b] etc.
  void scale(..);
  void rotate(..);
  void display(...); 
};

Seems like something CodeCogs should have, but can't find anything. Why don't you post it to CodeCogs. Keep it 'Private' initially make me an editor and I'll helping you out..

John

john\′s Photo
10 Nov 05, 9:02AM
Hey, just saw Lucian's comments, we posted at the same time.. Looks like equivalent ideas - though I'd embed a little more functionality with the data. Classes rather than Structures.
lucian\′s Photo
10 Nov 05, 9:20AM
I agree with the idea of encapsulating all 3D transformation routines inside the same class, which would also hold the coordinates of a single point. I am only thinking how the compiler would react when declaring an array of such objects, i.e.

Point P[100];

I know that it would only store the data, while there wouldn't be any copies of the functions inside the class, but is it really necessary to have these transformation functions linked to each point, or could they be declared outside the class ? This way they could be made into separate components on the website and may be downloaded separately. They could live in a category called "transformations" or something similar. Please let me know your opinion on this.

pacman\′s Photo
12 Nov 05, 8:58PM
Keep things simple and define a Point using a struct! Then get complex with your classes...

To save memory, define a static class called something like 'PolyMethods' - this simply contains methods for rotating/translating/scaling/etc an array of Points. This class is never instatiated - the Points are passed into the methods as a parameter.

Then, for neatness, define a virtual class called Polyhedron - this encapsulates an array of Points, and would also inherit all the (static) methods from PolyMethods.

Am I right in thinking that you can inherit from static to non-static (but not vice-versa, obviously) ??? This class would override the methods of PolyMethods (so I guess PolyMethods would need to be virtual too) with its own methods, which actually call the methods they override, to pass them the Points data.

Finally, you can define yourself an actual, instatiatable subclass, eg 'Sphere'. This would inherit methods and data from Polyhedron.

static virtual class PolyMethods
{
  protected:
 
    // rotates the given array of Points about &#40;0,0,0&#41;
    // by changing each Point's bearing and elevation by the amounts given
    void rotate(Point * points, double bearing_change, double elevation_change)
    {
       /* do all that trigonometry stuff here */    
    }
 
    // translate, scale, etc...
}
 
virtual class Polyhedron&#58; public PolyMethods
{
  protected:
 
    Point points[]; // not sure about this...
 
    // constructor 
    Polyhedron(Point* initial_data)
    {
      self.points = initial_data;
    }
 
    // rotate... this method gets the Points data, then passes it to the method it overrides
    void rotate(double bearing_change, double elevation_change)
    {
      super.rotate( self.points, bearing_change, elevation_change)
    }
 
    // translate, scale, etc...
};
 
class Sphere: public Polyhedron
{
  // In here you do something about knowing how many points there are
  // perhaps you override the constructor or something... I don't know
};

Or, I suppose, you might just make Polyhedron non-virtual and use it directly... But I'm not sure how you would deal with the variable number of points then. In fact I'm not sure anyway...

Feel free to correct me on any of this, my C++ is a bit rusty!

game_enginer\′s Photo
17 Jan 06, 2:41PM
hello folks... this thing is under construction...

there were few errors there... for example Vector and not Point should be used and to follow math further there should be operations on Vector by means on operators because that's what they are for.

whichever way....

Matrix4x4 * Vector3 would result in transforming a vector with matrix transformation and Matrix4x4 has member function setRotation (angle, direction.x, direction.y, direction.z); rotates around Direction vector by given amount of degrees.

Vector3D <float> v (x, y, z); Matrix4x4 <float> m; m.setRotation (angle, x, y, z); Vector3D <float> result = m * v; glVertex3fv (v.x. v.y, v.z); or even faster glVertex3fv (v.xyz);

or even cleaner.

Vec3f v (x, y, z); Matrix4x4 m; m.setRotation (angle, x, y, z); Vec3f result = m * v; glVertex3f (v.xyz);

would be same as glRotatef (angle, x,y,z); glVertex3f (x,y,z); // can't be faster if variables are separated

stuff is not ready yet... has to handle exceptions for v.normalize(); // if initial vector v is null vector then this might lead to divide by zero

I hope you can find this usefull when designing those yourself... mine are not yet suited for codecogs because it contains a lot of weird keywords ( work in progress )... however it should become available very very soon
Currently you need to be logged in to leave a message.