Whilst working on one of my projects this year for uni I was looking for some code to draw a cylinder between two points (using OpenGL). There were a couple of solutions out there, but they weren’t that great.

I couldn’t find one that worked reliably and simply (without lots of different if statements trying to catch different cases). Anyway, after a bit of thought I knocked this one out. It’s actually a lot simpler than you think…which is probably why people haven’t bothered to post it.

Anyway…enjoy some pseudo code:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | Vector3D a, b; (the two points you want to draw between) // This is the default direction for the cylinders to face in OpenGL Vector3D z = Vector3D(0,0,1);Â Â Â Â Â Â Â Â // Get diff between two points you want cylinder along Vector3D p = (a - b);Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â // Get CROSS product (the axis of rotation) Vector3D t = CROSS_PRODUCT (z , p); // Get angle. LENGTH is magnitude of the vector double angle = 180 / PI * acos ((DOT_PRODUCT(z, p) / p.LENGTH()); glTranslated(b.x,b.y,b.z); glRotated(angle,t.x,t.y,t.z); gluQuadricOrientation(YourQuadric,GLU_OUTSIDE); gluCylinder(YourQuadric, RADIUS, RADIUS, p.LENGTH(), SEGS1, SEGS2); |

Hope that helps someone out there.

## Comments

Tim L9:59 pm 15th February 2011I stumbled on your post today… And found it very useful.

I use a scene graph library called OpenSceneGraph

Based on your post… here is how to draw a cylinder between two points in Open Scene Graph

///////////////////////////////////////////////////////////////////////////////

// void AddCylinderBetweenPoints(osg::Vec3 StartPoint, osg::Vec3 EndPoint, float radius, osg::Vec4 CylinderColor, osg::Group *pAddToThisGroup)

/*

The following function creates a cylinder between two points with a given radius and color.

*/

void AddCylinderBetweenPoints(osg::Vec3 StartPoint, osg::Vec3 EndPoint, float radius, osg::Vec4 CylinderColor, osg::Group *pAddToThisGroup)

{

osg::ref_ptr geode = new osg::Geode;

osg::Vec3 center;

float height;

osg::ref_ptr cylinder;

osg::ref_ptr cylinderDrawable;

osg::ref_ptr pMaterial;

height = (StartPoint- EndPoint).length();

center = osg::Vec3( (StartPoint.x() + EndPoint.x()) / 2, (StartPoint.y() + EndPoint.y()) / 2, (StartPoint.z() + EndPoint.z()) / 2);

// This is the default direction for the cylinders to face in OpenGL

osg::Vec3 z = osg::Vec3(0,0,1);

// Get diff between two points you want cylinder along

osg::Vec3 p = (StartPoint – EndPoint);

// Get CROSS product (the axis of rotation)

osg::Vec3 t = z ^ p;

// Get angle. length is magnitude of the vector

double angle = acos( (z * p) / p.length());

// Create a cylinder between the two points with the given radius

cylinder = new osg::Cylinder(center,radius,height);

cylinder->setRotation(osg::Quat(angle, osg::Vec3(t.x(), t.y(), t.z())));

cylinderDrawable = new osg::ShapeDrawable(cylinder );

geode->addDrawable(cylinderDrawable);

// Set the color of the cylinder that extends between the two points.

pMaterial = new osg::Material;

pMaterial->setDiffuse( osg::Material::FRONT, CylinderColor);

geode->getOrCreateStateSet()->setAttribute( pMaterial, osg::StateAttribute::OVERRIDE );

// Add the cylinder between the two points to an existing group

pAddToThisGroup->addChild(geode);

}

KamaKase12:45 am 24th March 2011Awesome, I’m glad it helped. Thanks for sharing more code too.

Bear12:10 pm 6th April 2011it works

But could you explain why it works?

Given å…©é»žï¼Œç•«å€‹ cylinder é€£ä½ | å¸ç¿’ç†è¨˜12:16 pm 7th April 2011[…] è½‰è‡ªï¼šhttp://www.thjsmith.com/40/cylinder-between-two-points-opengl-c […]

KamaKase10:30 am 9th April 2011Sure.

We calculate p as the vector going from b to a (p = a – b).

z is simply the OpenGL default cylinder draw direction. If we did no rotation, it would be drawn in that orientation.

The cross product of z and p gives a vector perpendicular to both p and z, (this is t). This is then the vector the rotation pivots about.

We then use the dot product to obtain the angle needed to rotate (the division by the length is purely because I haven’t normalised p).

Then, we just perform the rotation.

Does that help?

Bear1:37 am 17th April 2011Thx, it helps

JC5:26 pm 18th February 2012Thanks!

## Leave a Comment