building tubes from line segments

i have a list of points that represent joins for line segments. one can think of bones, maybe. i want to build tubes (triangle meshes) from this lines with a given tube segment count. the reason for that is, that i want to render real lines in opengl, with lighting, shadows and so on. glLineWidth is not what i’m looking for.
the problem i have are the shared tube points on the joins. what i have tried is the following:

  1. interpolate the direction of the next and the previous line segment on a given join
  2. build x quaternions with that given axis and the angle = DEG2RAD(x*360/tube_segment_count);
    2.1 convert each quaternion into a matrix
    2.2 using the 2nd column (up vector) of that matrix, scale it by the tube radius, add the join position and store that vector
  3. connect all calculated vectors by triangles

so far, no problem. but when i build a simple circle with maybe 10 joins, some tube segments get twisted. i know, why this problem occurs, but i dont know of a robust solution to this problem.


Remembering back to a geometric modeller I wrote in college…

You’re essentially transforming a 2D circle into 3D along a piecewise linear curve and skinning up the vertices. At each source vertex on your curve, you compute an orientation that is aligned along the segment’s direction with an arbitrary rotation about the segment axis since that’s the only unspecified element.

The way I recall generating that quat was to compute a rotation from the Z-axis vector to the segment’s axis vector and define my circle in the X/Y plane. Then default rotation should be what you want, if I remember right.

I don’t know why you’d have the rotation about the segment be a function of the segment # unless you want that twist. To avoid twists, use the same rotation everywhere (use world-up vector, for example, unless your segments are vertical).

For nice banking, take the cross product of two adjacent segment directions and use this as your up vector. If there’s too much twisting, limit the rotation about the segments to a certain delta per segment, e.g., the weighted average of the current rotation with that of the one or two next and previous segments.


[This message has been edited by Cyranose (edited 02-01-2004).]

generating rotations about a specific axis puts me in too much trouble. an idea a have is to average connecting line segments, build a plane on the join with the averaged vector as normal, shot some rays from the starting join in direction of the line segment an calculate the ray plane intersection. for the next join, a shot the rays from the last found intersection points and so on.
so i dont have to care about any rotation stuff, i can loft any 2d shape you can think of, it only depends on the last join vertices and it perfectly avoids twisting.
it was just a thought while waiting for the bus and i haven’t implemented it yet, but it sounds quite well.
your suggestion is a great fallback for my cold winter day dream


Originally posted by jabe:
generating rotations about a specific axis puts me in too much trouble…

maybe you should try the following approach:

consider a part of your chain: three line segments AB, BC, CD passing through the points A, B, C, D. At point B we could build a vector Bbi, which disects the angle ABC. Bbi=AB/|AB|-BC/|BC|. Same thing at point C, bisector Cbi=BC/|BC|-CD/|CD|. If those vectors do not lie on the same plane with BC, then the tube WILL be twisted anyway. If not, then lines on these vectors (Bbi and Cbi) intersect at point Q. Vector Qt=QB*(1-t)+QC*t , 0<=t<=1, describes all points on BC in such a manner, that planes, perpendicular to BCQ and containing Qt describe all tube slices from B to C. You should build 2D-profile of your tube in that plane, and connect these sections.

[This message has been edited by Mega (edited 02-04-2004).]