0

Here is my problem. I have to move a torus along a circular trajectory on a bicubic surface.

However the vertical axis of the torus must be aligned with the surface normal at the given point Moreover the torus must face it's circular trajectory.

To manage this i took the normal vector and the Oy vector, made a cross and a dot product to find the angle i need and the axis to rotate around, it works. To manage the 2nd part, i took the actual coordinates of the torus, the next ones on the circular trajectory, made a vector, and did the same as previously described to found the angle and the axis, it works.

My problem is, i must apply the two rotations simultaneously and i can't find a way to do this. I tryed to Push/Pop Matrix i every possible way but i can't find a way out of this one. So i'm back to this...

    glPushMatrix();
    glTranslatef(pp -> x, pp ->y , pp ->z);

    glRotatef(*angledegree, vecortho -> x, vecortho -> y, vecortho -> z);
    glRotatef(*angledegreetang, tang -> x, tang -> y, tang -> z);

    tore(0.1, 0.3, 6, 4, 1);
    repere(0.6);
    glPopMatrix();

Any ideas? Sorry to bother you, it must be simple i think, but i don't see it. The first rotation always bugs the next one, whatever the order. vecortho is the axis vector computed from the surface normal and Oy. tang is the vector computed with my trajectory vector and Ox.

Jonathan
  • 1
  • 2

1 Answers1

0

Don't think in terms of rotations. Just think in terms of axes.

You want the torus's new Y axis to be translated to a particular new direction (the normal vector), its new Z axis to be translated to a particular new direction (the forward vector) and its X axis you don't care about.

So build the matrix that does this transformation and use it. Your vector class may differ from this example, and my vector math may be rusty as I haven't tested this code:

vector newY = normalVec;
vector newZ = forwardVec;
// We don't really care what X is, but it must be perpendicular to Y and Z. Swap Y and Z here if this ends up mirroring the object.
vector newX = normalize(cross(newY, newZ));

double matrix[16] = {
    newX.x,  newX.y,  newX.z,  0,
    newY.x,  newY.y,  newY.z,  0,
    newZ.x,  newZ.y,  newZ.z,  0,
    0,       0,       0,       1,
};
glPushMatrix();
glTranslatef(position of torus);
glMultMatrixd(matrix);
// draw torus
glPopMatrix();
user253751
  • 57,427
  • 7
  • 48
  • 90
  • Also, hopefully the fact that you can do this will give you some intuition about matrices. – user253751 May 08 '17 at 04:57
  • I implemented your solution. I don't know why or how but it shrinks my torus like some glScalef was applied :o. – Jonathan May 08 '17 at 14:33
  • Nevermind! I normalized the 3 vectors and it seems to work just fine! Tank you so much for your insight. I think i will manipulate matrices myself from now on! – Jonathan May 08 '17 at 15:03
  • @Jonathan This matrix basically tells OpenGL, for each vector `v` in the object, to change it to `newX*v.x + newY*v.y + newZ*v.z`. So the point (1,0,0) in the object becomes newX, the point (0,1,1) becomes newY+newZ, and so on. Basically it lets you change the direction that each of the object's axes points in. That's how you can use matrices for rotations (they can also be used for translations, but that part is zero in this particular matrix). Also you can change the length of newX/newY/newZ to do scaling - here we don't want scaling so they should all be normalized. – user253751 May 08 '17 at 21:03