Jump to content
  • Advertisement
Sign in to follow this  
Max_Payne

Raytracing Oriented Cylinders

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

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have seen equations for points on the surface of a cylinder. However, those were for axis aligned cylinders. I would like to know if there is a simple equation for the points on the surface of an oriented cylinder that would have a direction vector.

Share this post


Link to post
Share on other sites
Advertisement
Guest Anonymous Poster
just transform your ray by the cylinders inverse transform and do the axis aligned method

Share this post


Link to post
Share on other sites
Quote:
Original post by Anonymous Poster
just transform your ray by the cylinders inverse transform and do the axis aligned method


Now there has to be a more efficient and more logical method... Involving the axis vector of the cylinder.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
That's the more wefficient and logical way

Share this post


Link to post
Share on other sites
Well, how do you do that without using transform matrices? I'm looking for a simple say, and it seems to me like there would be a way to obtain a vector equation for the oriented cylinder.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Well it sound like you know how to solve it then.
But in my experience of all the ways you can find
transforming the line to the local space of the cylinder is the simplest and more efficient, because it eliminates some of the degree of fredom on the problem. That is what matrices are for, they simplify calculations they do not make then more difficult.
Ant way if you find a better way let my know.

Share this post


Link to post
Share on other sites
Well, I've been thinking about it, and I think I'm on the right track. We simply have to use the properties of a cylinder. I will start with infinite cylinders. Limiting the length should then be rather trivial.

We define an oriented cylinder by 3 parameters:
- An origin point (3D vector)
- A direction (3D vector)
- A radius

As you can see, the cylinder has an origin and a direction. Its basically just a line (or ray, but we don't limit it to only one direction), with a radius around it, that is, all points on its surface are equidistant from the axis ray.

For a ray, we know that the distance between the ray origin and the closest point to a random point in space is equal to:

1) OrigDistance = DotProduct(RayDirection , SpacePoint - RayOrigin)

We can actually get the closest point on the cylinder axis by applying this principle:

2) AxisPoint = CylOrigin + DotProduct(SpacePoint - CylOrigin) x CylDirection

Then, we know that the distance between a point on the surface is equal to the radius of the cylinder... So we substitute spacepoint by the point which should be the intersection of the ray and the cylinder:

3) Distance(RayPoint, CylOrig + Dot(RayPoint - CylOrig) x CylDir) = R

Now, its a matter of substituting the ray intersection point by its definition:

4) RayPoint = RayOrig + t x RayDir

Then we isolate t, and since this involves a square root, there should be two possible values for it, which is coherent with the fact that a ray should intersect a cylinder in two points, unless it intersects exactly on the surface.

This should work right. If anyone wants to bother isolating t, I'm going to sleep for the moment, and this might be helpful to others ;) Otherwise I'm going to have to re-check my linear algebra books tommorow.

Share this post


Link to post
Share on other sites
ive tried both methods, and there wasnt a significant difference in speed between either in my implementation.

however, i stuck with the intersection in cylinder space thing, because it allowes all sorts of funky squashed cylinders aswell.

however, calculating normals in worldspace has a catch: you should first multiply the normal with the cylinders adjunct matrix, then normalize it.
example: PositiontoNormal = WorldtoLocal.Transpose() * XYPlane * WorldtoLocal;
this will transform any point in worldspace on the surface of a z-aligned cylinder to an unnormalized normal in worldspace.

also, you can just normalize by dividing by a radius, but youll have to do a full normalize, which you might not find too appealing.

here is my code for an arbitrarily aligned cylinder:


void Trace(Ray ray){
//relative distance
Vector3 r;
r.x = Void.World.Position.x - ray.pos.x;
r.y = Void.World.Position.y - ray.pos.y;
r.z = Void.World.Position.z - ray.pos.z;

Vector3 t1;
t1.x = ray.dir.y*axis.z - ray.dir.z*axis.y;
t1.y = ray.dir.z*axis.x - ray.dir.x*axis.z;
t1.z = ray.dir.x*axis.y - ray.dir.y*axis.x;

Vector3 t2;
t2.x = r.y*axis.z - r.z*axis.y;
t2.y = r.z*axis.x - r.x*axis.z;
t2.z = r.x*axis.y - r.y*axis.x;

float A, B, C, D;
A = t1.x*t1.x + t1.y*t1.y + t1.z*t1.z;
B = (t1.x*t2.x + t1.y*t2.y + t1.z*t2.z) * 2;
C = t2.x*t2.x + t2.y*t2.y + t2.z*t2.z - Radius*Radius;
D = B*B - 4*A*C;

if (D >= 0){
D = sqrt(D);

float min, max;
max = (B + D) / (2 * A);
if (max > 0){ //in front of ray
min = (B - D) / (2 * A);
if (min > 0){ //ouside
if (max > 1){ //doesnt exit
if (min > 1){ //doesnt enter
iv.Reset(false);
}else{ //ends inside
iv.Set(on, min, false);
}
}else{ //goes trough
iv.Set(on, min, off, max, false);
}
}else{ //inside
if (max > 1){ //doesnt exit
iv.Reset(true);
}else{ //exits
iv.Set(off, max, true);
}
}
return;
}
}
//reset interval
iv.Reset();
}

Share this post


Link to post
Share on other sites
equation of infinite cylinder

((P - C) x H)^2 = r^2


it's like a sphere where

(P - C)^2 = r^2

and H being the direction of the cylinder

second order equation, ect...

if H not normalised

((P - C) x H)^2 = r^2 * (H.Dot(H))

also, to deal with caps, it's just like when doing box-ray tests. YOu have to work with slabs.

Share this post


Link to post
Share on other sites
Thank you Mr Oliii. I knew it had to be possible to simplify it. Now its just a matter of substituting the ray equation and isolating t. Just one detail though.

((P - C) x H)^2 = r^2

By this, do you mean cross product with H? And if so, that would be magnitude of the cross product of (P - C) with H, squared?

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!