Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 5 of 5

Thread: glucylinder between two points

Hybrid View

  1. #1
    Junior Member Newbie
    Join Date
    Jul 2007
    Posts
    3

    glucylinder between two points

    I have a problem with trying to render a glucylinder between two 3d points.

    Based on the code from here
    http://home.neo.rr.com/jparris/OpenG...%202%20pts.htm

    This seems to work for all cases except when the cylinder is aligned to the Y axis. ie from (0,-5,0) to (0,+5,0). In that case the Y axis aligned cylinder either flickers (like its rotation is being flipped around each frame) or it renders from the first point out in space the opposite direction to the second point.

    Can anyone help with the right "if then" code to fix the Y axis problem? I have done a lot of searching on these forums and the web trying to find working code. It will definitely help me and I am sure others who come here looking for the solution in the future.

    Thanks,
    Jason.


    Code :
     
    procedure CylinderGL(p1,p2:point3d;r1,r2:double;precision:integer);
    var quadratic:pGLUquadricObj;
        height,dx,dy,dz:double;
        v,vx,vy,vz,rx,ry,rz,zero,ax,r2d:double;
    begin
         r2d:=180/pi;
         //length of cylinder
         dx:=p1.x-p2.x;
         dy:=p1.y-p2.y;
         dz:=p1.z-p2.z;
         height:=sqrt(dx*dx+dy*dy+dz*dz);
     
         glpushmatrix;
         gltranslatef(p1.x,p1.y,p1.z);
     
         //now rotate the matrix into position
     
    	   // orientation vectors
    	   vx:=p2.x-p1.x;	//	component in x-direction
    	   vy:=p2.y-p1.y;	//	component in y-direction
    	   vz:=p2.z-p1.z;	//	component in z-direction
     
     
         v:=sqrt(vx*vx+vy*vy+vz*vz);	// cylinder length
     
    	   // rotation vector, z x r
    	   rx:=-vy*vz;
    	   ry:=+vx*vz;
    	   ax:=0.0;
         if vz=0 then
         begin
    		      ax:=r2d*arccos(vx/v);	// rotation angle in x-y plane
    		      if vx<=0 then ax:=-ax;
         end
         else
         begin
    		      ax:=r2d*arccos(vz/v);	// rotation angle
    		      if vz<=0 then ax:=-ax;
         end;
     
         if vz=0 then
         begin
    			glRotated(90.0, 0, 1, 0.0);			// Rotate & align with x axis
    			glRotated(ax, -1.0, 0.0, 0.0);		// Rotate to point 2 in x-y plane
     
         end
         else
         begin
    			glRotated(ax, rx, ry, 0.0);			// Rotate about rotation vector
         end;
     
         quadratic:=gluNewQuadric;			// Create A Pointer To The Quadric Object ( NEW )
    	   gluQuadricNormals(quadratic, GLU_SMOOTH);	// Create Smooth Normals ( NEW )
    	   gluQuadricTexture(quadratic, FALSE);		// Create Texture Coords ( NEW )
         gluCylinder(quadratic,r1,r2,height,precision,precision);		// Draw A cylinder
         glpopmatrix;
    end;

  2. #2
    Senior Member OpenGL Pro
    Join Date
    Sep 2004
    Location
    Prombaatu
    Posts
    1,401

    Re: glucylinder between two points

    Draw a cylinder of radius R between the points A and B:

    Let the unit vector B - A be the z-axis of a Frenet frame located at A. With this frame on top of the modelview stack,
    call gluCylinder with top = base = R and height = length(B - A), OR render a unit cylinder (base = top = height = 1) but prescale the frame's xy-axes by the radius and use B - A as the z-axis. For extra credit, do all this using a geometry shader instead ;-)

  3. #3
    Junior Member Newbie
    Join Date
    Jul 2007
    Posts
    3

    Re: glucylinder between two points

    Same question, can anyone see where in the code it fails for Y axis aligned cylinders?

    Problem is calculating the right rotation angles. After the gltranslatef and before the glnewquadric.

    This is so close to working. If anyone has a working snippet of code or can understand the math please help.

    Once it works I will post the full working procedure for people to find in the future (so all you gurus can concentrate on better problems).

    Thanks,
    Jason.

  4. #4
    Junior Member Newbie
    Join Date
    Jul 2007
    Posts
    3

    Re: glucylinder between two points

    An update on this...

    The flickering of the cylinder is fixed. Looks like it was due to me not calling gludeletequadric(quadratic) at the end of the procedure. But still strange that it only effected cylinders aligned with the Y axis.

    If I reverse the P1 and P2 points when calling the procedure then the cylinders on the Y axis do correctly join between the two points. So adding a small check at the start of the procedure to swap the points if required gets it all working.

    But, if anyone can see the error in the math so I can omit this swap check it would be very helpful.

    Thanks,
    Jason.

    Here is the working code if anyone needs this sort of thing in the future.

    Code :
     
    procedure CylinderGL(p1,p2:point3d;r1,r2:double;precision:integer);
    var quadratic:pGLUquadricObj;
        height,dx,dy,dz:double;
        v,vx,vy,vz,rx,ry,ax,r2d:double;
        tmp:point3d;
    begin
         if (p1.x=p2.x) and (p1.z=p2.z) and (p1.y<p2.y) then
         begin
              tmp:=p1;
              p1:=p2;
              p2:=tmp;
         end;
     
         r2d:=180/pi;
         //length of cylinder
         dx:=p1.x-p2.x;
         dy:=p1.y-p2.y;
         dz:=p1.z-p2.z;
         height:=sqrt(dx*dx+dy*dy+dz*dz);
     
         glpushmatrix;
         gltranslatef(p1.x,p1.y,p1.z);
     
    	   // orientation vectors
    	   vx:=p2.x-p1.x;	//	component in x-direction
    	   vy:=p2.y-p1.y;	//	component in y-direction
    	   vz:=p2.z-p1.z;	//	component in z-direction
     
         v:=sqrt(vx*vx+vy*vy+vz*vz);	// cylinder length
     
         // rotation vector, z x r
    	   rx:=-vy*vz;
    	   ry:=+vx*vz;
    	   ax:=0.0;
         if vz=0 then
         begin
    		      ax:=r2d*arccos(vx/v);	// rotation angle in x-y plane
    		      if vx<=0 then ax:=-ax;
         end
         else
         begin
    		      ax:=r2d*arccos(vz/v);	// rotation angle
    		      if vz<=0 then ax:=-ax;
         end;
     
         if vz=0 then
         begin
    			    glRotated(90.0, 0, 1, 0.0);			// Rotate & align with x axis
    			    glRotated(ax, -1.0, 0.0, 0.0);		// Rotate to point 2 in x-y plane
         end
         else glRotated(ax, rx, ry, 0);			// Rotate about rotation vector
     
         //create a pointer to the quadric object
         quadratic:=gluNewQuadric;
         //tell it to smooth normals
    	   gluQuadricNormals(quadratic, GLU_SMOOTH);
         //draw the clyinder
         gluCylinder(quadratic,r1,r2,height,precision,precision);		// Draw A cylinder
         glpopmatrix;
         //delete the pointer
         gluDeleteQuadric(quadratic);
    end;

  5. #5
    Junior Member Newbie
    Join Date
    Aug 2007
    Location
    Sydney, Australia
    Posts
    3

    Re: glucylinder between two points

    Possibly a more long-winded way to do it.
    http://dbfinteractive.com/index.php?...30024#msg30024

    Jim

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •