Jump to content
  • Advertisement
Sign in to follow this  

Normal Computation, Cylinder/Cone

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

Important Information

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

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!