This project, completed as part of the coursework at the Benemérita Universidad Autónoma de Puebla, focuses on implementing free rotation of a 3D pyramid. The objective is to perform rotations around arbitrary axes using matrix transformations. This enhances understanding of 3D transformations and their applications in computer graphics.
Rotations in 3D involve altering the coordinates of an object around a specified axis. This project targets free rotation by calculating unit vectors, applying rotation matrices for each axis, and using inverse matrices for returning to the original position. The implementation uses matrix multiplication to perform the necessary transformations.
- Implement free rotation for a 3D pyramid using matrix transformations in OpenGL.
- Apply learned concepts to rotate the pyramid around any specified axis.
- Develop an understanding of 3D rotations and their applications in computer graphics.
- Initialization: Set up the OpenGL environment and window properties.
- Rotation Functions: Implement functions for rotating the pyramid around arbitrary axes.
- Matrix Operations: Utilize matrix multiplication for applying transformations.
- Animation Loop: Continuously apply rotations to animate the 3D pyramid.
The project includes the following main components:
This function sets up the OpenGL environment, defining the color of the window and the projection parameters.
void init(void) {
glClearColor(0.0, 0.0, 0.0, 1.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60, 1.0, 1.0, 30.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0, 0.0, -3.0);
}
This function handles the free rotation of the pyramid along any specified axis. It first calculates the unit vector and necessary matrices, applies the rotation, and then translates back.
void Operaciones3D::RotacionLibre(float theta, float p1[3], float p2[3]) {
float V, a, b, c, d;
// Calculate the unit vector
V = sqrt(pow(p2[0] - p1[0], 2) + pow(p2[1] - p1[1], 2) + pow(p2[2] - p1[2], 2));
if (V < 0) V = -V;
a = (p2[0] - p1[0]) / V;
b = (p2[1] - p1[1]) / V;
c = (p2[2] - p1[2]) / V;
d = sqrt(pow(b, 2) + pow(c, 2));
// Case for the X axis
if (d == 0) {
translate(-p1[0], -p1[1], -p1[2]);
rotateX(DegToRad(theta));
MultM(R, T, A);
translate(p1[0], p1[1], p1[2]);
MultM(T, A, A);
} else { // For Y and Z axes
// Translation
translate(-p1[0], -p1[1], -p1[2]);
// Calculate RX(alpha)
LoadIdentity(R);
R[1][1] = c / d;
R[1][2] = -b / d;
R[2][1] = b / d;
R[2][2] = c / d;
MultM(T, R, A);
// Calculate RY(beta)
LoadIdentity(R);
R[0][0] = d;
R[0][2] = a;
R[2][0] = -a;
R[2][2] = d;
MultM(A, R, A);
// Calculate RZ(theta)
LoadIdentity(R);
R[0][0] = cos(DegToRad(theta));
R[0][1] = -sin(DegToRad(theta));
R[1][0] = sin(DegToRad(theta));
R[1][1] = cos(DegToRad(theta));
MultM(A, R, A);
// Calculate RY-1(beta)
LoadIdentity(R);
R[0][0] = d;
R[0][2] = -a;
R[2][0] = a;
R[2][2] = d;
MultM(A, R, A);
// Calculate RX-1(alpha)
LoadIdentity(R);
R[1][1] = c / d;
R[1][2] = b / d;
R[2][1] = -b / d;
R[2][2] = c / d;
MultM(A, R, A);
// Inverse translation
translate(p1[0], p1[1], p1[2]);
MultM(A, T, A);
}
}
This function applies a translation to the 3D object by modifying its coordinates.
void translate(float dx, float dy, float dz) {
float T[4][4] = {
{1, 0, 0, dx},
{0, 1, 0, dy},
{0, 0, 1, dz},
{0, 0, 0, 1}
};
MultM(R, T, A);
}
These functions define the rotation matrices for the X, Y, and Z axes and multiply them with the transformation matrix.
void rotateX(float theta) {
float R[4][4] = {
{1, 0, 0, 0},
{0, cos(theta), -sin(theta), 0},
{0, sin(theta), cos(theta), 0},
{0, 0, 0, 1}
};
MultM(T, R, A);
}
void rotateY(float theta) {
float R[4][4] = {
{cos(theta), 0, sin(theta), 0},
{0, 1, 0, 0},
{-sin(theta), 0, cos(theta), 0},
{0, 0, 0, 1}
};
MultM(T, R, A);
}
void rotateZ(float theta) {
float R[4][4] = {
{cos(theta), -sin(theta), 0, 0},
{sin(theta), cos(theta), 0, 0},
{0, 0, 1, 0},
{0, 0, 0, 1}
};
MultM(T, R, A);
}
This function multiplies two 4x4 matrices.
void MultM(float A[4][4], float B[4][4], float C[4][4]) {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
C[i][j] = 0;
for (int k = 0; k < 4; k++) {
C[i][j] += A[i][k] * B[k][j];
}
}
}
}
The project initializes a graphical window and applies free rotations to the pyramid along any specified axis. The rotation is continuous, providing a dynamic visual representation of the 3D transformations.