DrGonzo

09-15-2010, 02:05 PM

Hey all,

I suspect this problem to be quite trivial, but I just don't see it.

The main idea is that the code below connects 2 points by means of a beam (a square through both points, with the point as the center of the 'top' and 'bottom', perpendicular to the direction) and 4 quads to complete the beam.

This works well, but now I need the world coordinates of the vertices that make up the corners of my quads. (because I built my collision detection around them).

The translation (glTranslated) can be 'compensated' by adding the value of the transX, transY and transZ to the corresponding X,Y and Z element (and in case of the second quad, v also needs to be added).

But how would one 'compensate' the rotation (glRotated), given that I know the angle and the axis it rotates around?

I was thinking that I needed to create my own rotation matrix, and use that to multiply my points with, but I don't get how I do that. Wikipedia suggested that I should use a certain matrix when using an arbitrary axis, but that it should rotate around a unit vector. But where does this unit vector come from?

In the code below transX,transY and transZ and transX2,transY2, transZ2 are values of two points in space in WORLD coordinates. They originate from a member matrix that holds the global transformation of a certain joint.

TransX..Z contains the 3 translation values from the current joint TransX2..Z2 contains the 3 translation values from the next joint.

The rest of the code is then used to calculate the angle and axis to rotate about, and afterwards the 8 points of the 2 quads (which form the top and bottom cap of the beam) are calculated.

*I make use of a custom vector library, plMath.

double vx = transX2-transX;

double vy = transY2-transY;

double vz = transZ2-transZ;

//handle the degenerate case of z1 == z2 with an approximation

if(vz == 0.0)

vz = .0001;

double v = sqrt( vx*vx + vy*vy + vz*vz );

double ax = (180 / M_PI) * acos( vz/v );

if ( vz < 0.0 )

ax = -ax;

double rx = -vy*vz;

double ry = vx*vz;

glPushMatrix();

//draw the beam

glTranslated( transX,transY,transZ );

glRotated(ax, rx, ry, 0.0);

//with sides

plVector3d p11 = plVector3d(-0.01, 0.01, 0.0);

plVector3d p12 = plVector3d(0.01, 0.01, 0.0);

plVector3d p13 = plVector3d(0.01, -0.01, 0.0);

plVector3d p14 = plVector3d(-0.01, -0.01, 0.0);

plVector3d p21 = plVector3d(-0.01, 0.01, v);

plVector3d p22 = plVector3d(0.01, 0.01, v);

plVector3d p23 = plVector3d(0.01, -0.01, v);

plVector3d p24 = plVector3d(-0.01, -0.01, v);

glPopMatrix();

I suspect this problem to be quite trivial, but I just don't see it.

The main idea is that the code below connects 2 points by means of a beam (a square through both points, with the point as the center of the 'top' and 'bottom', perpendicular to the direction) and 4 quads to complete the beam.

This works well, but now I need the world coordinates of the vertices that make up the corners of my quads. (because I built my collision detection around them).

The translation (glTranslated) can be 'compensated' by adding the value of the transX, transY and transZ to the corresponding X,Y and Z element (and in case of the second quad, v also needs to be added).

But how would one 'compensate' the rotation (glRotated), given that I know the angle and the axis it rotates around?

I was thinking that I needed to create my own rotation matrix, and use that to multiply my points with, but I don't get how I do that. Wikipedia suggested that I should use a certain matrix when using an arbitrary axis, but that it should rotate around a unit vector. But where does this unit vector come from?

In the code below transX,transY and transZ and transX2,transY2, transZ2 are values of two points in space in WORLD coordinates. They originate from a member matrix that holds the global transformation of a certain joint.

TransX..Z contains the 3 translation values from the current joint TransX2..Z2 contains the 3 translation values from the next joint.

The rest of the code is then used to calculate the angle and axis to rotate about, and afterwards the 8 points of the 2 quads (which form the top and bottom cap of the beam) are calculated.

*I make use of a custom vector library, plMath.

double vx = transX2-transX;

double vy = transY2-transY;

double vz = transZ2-transZ;

//handle the degenerate case of z1 == z2 with an approximation

if(vz == 0.0)

vz = .0001;

double v = sqrt( vx*vx + vy*vy + vz*vz );

double ax = (180 / M_PI) * acos( vz/v );

if ( vz < 0.0 )

ax = -ax;

double rx = -vy*vz;

double ry = vx*vz;

glPushMatrix();

//draw the beam

glTranslated( transX,transY,transZ );

glRotated(ax, rx, ry, 0.0);

//with sides

plVector3d p11 = plVector3d(-0.01, 0.01, 0.0);

plVector3d p12 = plVector3d(0.01, 0.01, 0.0);

plVector3d p13 = plVector3d(0.01, -0.01, 0.0);

plVector3d p14 = plVector3d(-0.01, -0.01, 0.0);

plVector3d p21 = plVector3d(-0.01, 0.01, v);

plVector3d p22 = plVector3d(0.01, 0.01, v);

plVector3d p23 = plVector3d(0.01, -0.01, v);

plVector3d p24 = plVector3d(-0.01, -0.01, v);

glPopMatrix();