Ray - cylinder intersection

Hi,

I know how to check if a ray intersects with a sphere and a polygon. I am now trying to do the same for a cylinder.

The best idea I’ve come up with so far is quite similar to my solution for ray-sphere intersection: substitute the equation of the ray into the equation of the sphere and solving quadratically.
The problem with this is that the equation of the cylinder assumes that the cylinder is at the origin and that it is a unit cylinder. My cylinders have undergone transformations such as rotations and translations (so it’s not necessarily based at the origin) and are not unit cylinders. My source for this is:

ray-cylinder intersection site

Can anyone please help me with this? If not, can anyone give me info about alternative ray-cylinder intersection techniques (preferably simple and accurate ones)? Any help is greatly appreciated.

Thanks,
Ramsey

Originally posted by ramsey:

The problem with this is that the equation of the cylinder assumes that the cylinder is at the origin and that it is a unit cylinder. My cylinders have undergone transformations such as rotations and translations (so it’s not necessarily based at the origin) and are not unit cylinders.

Transform your ray by the inverse of your cylinder matrix this way you have the ray in the local space of the cylinder. Then you can use the equation to find the intersection.

Hope this help

Thanks for your response. I will look into it after I have pursued my own solution to the problem that I came up with:

Imagine a vector that runs through the cylinder (through its centre). The first point of the vector is at one end of the cylinder and the other point of the vector is at the other end of the cylinder. You’ve basically got a ray running through the cylinder. If I was to place spheres at intervals along the ray then you would end up with a cylinder whose internal space is almost entirely filled with spheres. I could then check for intersection with the cylinder by checking for intersection with each of these spheres. This approach isn’t 100% accurate (there will be some internal space in the cylinder that isn’t covered due to the gaps between adjacent spheres), however you can increase the accuracy by decreasing the distance between adjoining spheres. Obviously the greater the number of spheres (and thus the accuracy) the greater the number of calculations.
I have started work on this approach and am having a problem: when I rotate my cylinder and vector about the x-axis by -45 degrees, the vector running through the cylinder is shrinking slightly and being rotated by slightly more than -45 degrees (so it’s no longer running through the centre of the cylinder). Here is my code:


  

// angle to rotate cylinder and vector by
float angle = -45.0;

GLUquadricObj	*q;

// used to convert radians to degrees
#define PI 3.14159265


// draw cylinder
glPushMatrix();
    glColor3f(0.0f,0.0f,1.0f);
    q = gluNewQuadric();
    glRotated(angle, 1.0, 0.0, 0.0);
    gluQuadricDrawStyle(q, GLU_LINE);
    gluCylinder(q, 0.1f, 0.1f, 1, 6, 6);
glPopMatrix();


// coordinates of the two points making up the
// vector
float ax = 0.0, ay = 0.0, az = 0.0;
float bx = 0.0, by = 0.0, bz = 1.0;

// apply the manual rotate calculations to the
// points of the vector. Multiplying by PI and
// then diving by 180 converts radians to degrees
ax = ax;
ay = ay*cos((angle*PI)/180) - 
       az*sin((angle*PI)/180);
az = ay*sin((angle*PI)/180) +  
       az*cos((angle*PI)/180);

bx = bx;
by = by*cos((angle*PI)/180) - 
       bz*sin((angle*PI)/180);
bz = by*sin((angle*PI)/180) + 
       bz*cos((angle*PI)/180);


// draw the vector running through the cylinder
glColor3f(1.0f,0.0f,0.0f);
glBegin(GL_LINES);
    glVertex3f(ax, ay, az);
    glVertex3f(bx, by, bz);
glEnd();

When I use the glRotated() method on the vector instead of manually calculating the points myself, the problem disappears. Why are my manual rotate calculations on the vector causing these problems?
I need to calculate the two points of the vector manually because I need to store these points so that I can place the spheres along the ray. I got all my maths for calculating the rotation from the following page:

rotations tutorial

Thanks,
Ramsey

OK, spotted the problem… the skew i’m experiencing is caused by me changing the value of ly1 and ly2 before calculating lz1 and lz2. I need to cache ly1 and ly2 and use those cached values:

  

float temp = 0.0;

temp = ly1;

lx1 = lx1;
ly1 = ly1*cos((angle*PI)/180.0) - 
        lz1*sin((angle*PI)/180.0);
lz1 = temp*sin((angle*PI)/180.0) + 
        lz1*cos((angle*PI)/180.0);