• Advertisement
Sign in to follow this  

Normal Computation, Cylinder/Cone

This topic is 2815 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

Hello all, I wasnt sure if this should have gone in the graphics forum or the math one but since it has to do mainly with computation, I decided that posting here would be the correct choice.

Anyway, I've managed to construct several parametric objects (uv-sphere, torus, cuboid, quad, cylinder/cone) algorithmacially and am now faced with the task of computing the vertex normals for each object. I have been able to construct the normals of all but the cylinder/cone object, having tried several times to do it, I turn to you in hopes of finding the correct formula.

If you have ever used 3Ds Max, my algorithm takes the same parameters and produces the same results when creating a cone. There are 6 parameters; radius1 (bottom), radius2 (top), height, sides, heightsegs, and capsegs.

I need to ensure that the correct normals are generated regardless of the difference between the radii and how tall the cylinder/cone is.

Any help would be appreciated, and if an image of the cone/cylinder is needed I would be happy to oblige.

Thanks all!

PS: I have what is called "programmer math" (i.e. I am not traditionally trained, no A levels or anything of the like), so any effort to explain in a clear and concise manner as opposed to slamming me with "math talk" would be appreciated although not required (It will just take me a little while longer to understand what your saying)

EDIT: This is the closest ive been able to get so far. but im unsure if the normals are exactly perpendicular to the surface.

v.normal.x = v.pos.x; // = dr * cos(theta) where dr is a linear interpolation between radius1 and radius2
v.normal.y = (radius1 - radius2) / height; // problematic maybe?
v.normal.z = v.pos.z // = dr * sin(theta)

[Edited by - CodeCriminal on July 2, 2010 6:17:12 PM]

Share this post

Link to post
Share on other sites
If your cone is centered about the origin, e.g., if <0,??,0> is the axis that goes through the center line of the cone, then your x and z components are good, but your y component is bad. Also, your normal is not a unit length in general. Below I derive the normal, using your commented out approach...with trig and the theta angle. So, the derivation below assumes the cone axis is parallel to the y axis but it doesn't care if the cone axis passes through the origin.

Looks like your cone axis is parallel to the y axis. So, lets say that theta = 0 and y = 0 is the x axis. Then a vector from the bottom edge of the cone to the top edge of the cone in the xy plane is given by the 3 vector:

A' = <r1-r2, height, 0>

Since theta = 0, z is 0

Now, lets normalize that to make it unit length. Let B be the length of A':

B = sqrt(((r1-r2) * (r1-r2)) + (height * height));

Then, we can generate a unit length version of A', calling it A:

A = <(r1 - r2)/B, height/B, 0>

So, now you have A being a unit vector in the direction from the base of the cone to the top of the cone. Still working within the xy plane, it is rather easy to do a 90 rotation to get a vector perpendicular to the cone. This will be your unit normal for points on the cone that lie in the xy plane:

N_xy = <height/B, -(r1-r2)/B, 0>

Basically, within a plane, swapping the two components and negating one of them gives you a vector perpendicular to the starting vector. I just picked the version that gets you a vector pointing towards the outside of the object. (Sorry I can't post a pic.)

So, now, a generalized normal on the surface of the cone will have the same y coordinate for all. The magnitude of the x coordinate of N_xy becomes the magnitude of the xz component for any value of theta. You can use cos and sin to move N_xy around the cone. So, for any given theta, e.g., for any point on the cone regardless of position along the height, the unit normal would be:

N = <cos(theta) * height/B, -(r1-r2)/B, sin(theta) * height/B>

I think that's right. I'll let you double check it for me, okay?!

Share this post

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

  • Advertisement