# OpenGL Help with linear algebra + openGL question...

This topic is 3669 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

So I am trying to draw a line with an arrow at the end. For the lines I am using GL_LINES, and for the arrow at the end, I am using gluCylinder(), with the base set to zero to make a cone for the arrow head. What I cannot for the life of me seem to figure out, is how to orient the cone so that it is coincident with the original line. Psuedocode looks something like: 1. Draw line 2. Calculate 3-vector coincident with line: N = TO - FROM 3. glTranslate from origin to TO 4. glRotate so the z-axis (where gluCylinder draws) is coincident with N 5. call gluCylinder() Results: the point of the cone in every case is located at TO, but the angle of rotation for each cone is different, and not at all coincident with N. For the rotation I am using:
vector<float> normal(3);
float vx =tTo[0]-tFrom[0];     // tTo and tFrom are the endpoints of the line
float vy =tTo[1]-tFrom[1];
float vz =tTo[2]-tFrom[2];
float dr = sqrt(vx*vx+vy*vy+vz*vz); // use dr to normalize the vector
normal[0]=vx/dr;
normal[1]=vy/dr;
normal[2]=vz/dr;
...
...
float rTd = 180.0 / 3.14159265;   // conversion from radians to degrees
float theta = rTd*acos(n[2]);     // angle through which to rotate, from dot product
glRotatef(theta,-1.0*normal[1],-1.0*normal[0],0);  // axis of rotation from cross product


Any help on this would be much appreciated! Thanks, Gary

##### Share on other sites
I don't check all your calculations but I just notice that I don't use the glRotatef function as you do.

For instance I would use it as follows:
glRotatef(theta,1.0,0.0,0.0); // rotation around x-axis
glRotatef(theta2,0.0,1.0,0.0); // rotation around y-axis
glRotatef(theta3,0.0,0.0,1.0); // rotation around z-axis

From your vector N you have to calculate 3 angles to make your cylinder coincident with your line.

And remember to call glTranslatef(...) BEFORE glRotatef(...)

##### Share on other sites

So I tried an approach like that earlier, which looked like:

glPushMatrix();     glTranslatef(x, y, z);     glRotatef(90-rTd*atan(normal[2]/normal[1]),1.0,0,0);     glRotatef(90-rTd*atan(normal[2]/normal[0]),0,1.0,0);     glRotatef(rTd*atan(normal[0]/normal[1]),0,0,1.0);     gluCylinder(...);glPopMatrix;

Perhaps my calculations are off? It's been a while since trig in high school...

Thanks!
Gary

##### Share on other sites
Quote:
 Original post by Shirakana2I don't check all your calculations but I just notice that I don't use the glRotatef function as you do.For instance I would use it as follows:glRotatef(theta,1.0,0.0,0.0); // rotation around x-axisglRotatef(theta2,0.0,1.0,0.0); // rotation around y-axisglRotatef(theta3,0.0,0.0,1.0); // rotation around z-axisFrom your vector N you have to calculate 3 angles to make your cylinder coincident with your line.And remember to call glTranslatef(...) BEFORE glRotatef(...)
There's no need to use three rotations for this; one is plenty :)

@The OP: I didn't look at your code too carefully, but after computing the angle, you'll actually want to rotate about an axis that is perpendicular to both the reference vector (the z axis) and the desired direction vector ('normal' in your example code).

You can compute this vector using the cross product. I believe glRotate() can accept a non-unit axis of rotation, so there's no need to normalize it (I'm not sure what glRotate() does when presented with an axis that is near-zero-length though).

##### Share on other sites

The Red Book recommends this approach, too, using only one glRotate*() command where the angle is determined by the dot product of the two vectors, and the axis of rotation is the vector normal to the two vectors, which is given by the cross product. In the first post I tried to do this, but somehow it didn't work. Maybe my math is wrong?

A directed line has two endpoints, a from-point and a to-point, with coordinates given by the 3-vectors

from = (f1,f2,f3)

and

to = (t1,t2,t3)

Therefore the normal vector that would be coincident with this line is n = to - from,

n = (t1-f1,t2-f2,t3-f3)

Since the gluCylinder draws the cone (representing the arrow at the tip of the directed line) in the z-axis by default, the vector of the cone is

c = (0,0,1)

Then the angle between them, theta is given by the dot product

n dot c = |n|*|c| cos (theta)

and the angle theta = acos ( (n dot c) / (|n|*|c|) ),

so theta = acos ((t3-f3) / (sqrt(n1^2_n2^2+n3^2)*1)

The axis of rotation is given by the cross product,

n x c = (t1-f1,t2-f2,t3-f3) x (0,0,1) = (t2-f2, t1-f1, 0)

so the final rotate command should be

glRotatef(theta, t2-f2, t1-f1, 0);

but for some reason this doesn't work! does anyone know why?

thanks!
g

##### Share on other sites
If I remember well my maths lessons, n^c = (t2-f2, -T1 + F1, 0)
You may also normalize it before calling glRotate.

1. 1
2. 2
frob
16
3. 3
4. 4
5. 5

• 20
• 13
• 14
• 76
• 22
• ### Forum Statistics

• Total Topics
632145
• Total Posts
3004381

×