We were given an assignment in Computer Graphics to draw a cylinder in WebGL using libraries such as gl-matrix and cuon. That is to say, * not* using Three.js. We couldn’t find any tutorials that matched our problem, so hopefully this one will be of help to other students. If you don’t want to read all this, here is the code and here is the demo (sorry no controls, I wanted to keep it focused). :) I suppose this also works to show how to store color information in the same array as your vertices, and how to use .glsl files.

This example uses webgl-utils.js, webgl-debug.js, cuon-utils.js, and cuon-matrix.js. I’m assuming you’re already comfortable with WebGL syntax, vertex buffers, and different ways of drawing, so I won’t go into binding buffers etc. We’ll be drawing the bottom and top of the cylinder with **triangle fans** and the walls with **triangle strip**. Because that was our assignment.

First: A reminder of the difference between triangle **strips** and triangle **fans**:

## Triangle Strip

Every triangle shares two vertices. You first define 3 vertices to create the first triangle, you then only need to define one new vertex to create the next triangle, reusing the previous two vertices. If the number of triangles you want to draw, you will need vertices.

## Triangle Fan

The name might be confusing as it does not actually draw a nice, circular fan by default; All the triangles of a triangle fan share a *common, central, vertex* (in the image, A). You need to define 3 vertices for the first triangle, then 2 new vertices for the next. If the number of triangles you want to draw, you will need vertices.

## The Math

The hard part about drawing a cylinder is figuring out how to draw a circle. Once you have a circle (the cylinder’s bottom), you can use the exact same values for and , but with a different in order to define the cylinder’s top. Once you have the top and the bottom you can use the same vertices to draw the walls!

1 2 3 4 |
cylinderBotVertices.push(x, y, z); //Bottomvertices cylinderSideVertices.push(x, y, z); //Sidevertices along the bottom cylinderSideVertices.push(x, y+2, z); //Sidevertices along the top with y = 2 cylinderTopVertices.push(x, y+2, z); //Topvertices with y = 2 |

Any given circle with a radius can be described as with its origin in , where and , and . I choose so those are now out of the equations.

Our parametric equations are now

Where t is the angle between the x-axis and the segments that make up the circle. First we need to decide how many segments (triangles) we should use. 4 segments will give you a cube, more than 4 will give you a pentagonal prism which becomes a cylinder if we use enough segments. The more segments, the smaller the angle will be per segment (imagine dividing a pie into 18 pieces vs 4 pieces).

I will create a function that will take a number of segments as input and generate the vertices needed for the top, bottom and sides.

## The Code

This is the function:

1 2 3 4 5 6 7 8 9 |
function AddPoints(segments) { a=0, b=0, y=0; //The origin r = 1.0, g = 1.0, b = 1.0, al = 1.0; rbt = 1.0, gbt = 0.0, bbt = 0.0; theta = (Math.PI / 180) * (360 / segments); //Degrees = radians * (180 / π) ... } |

The second and third line is color and alpha values that I store in the same array as the vertices.

The fourth line defines the angle (in radians!) of each segment. gives an angle in *degrees* per segment. The formula for converting radians to degrees is . So to find the angle in radians we flip it around: . There’s our ! Now we just need to iterate it from 0 to .

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
function AddPoints(segments) { a=0, b=0, y=0; //The origin r = 1.0, g = 1.0, b = 1.0, al = 1.0; rbt = 1.0, gbt = 0.0, bbt = 0.0; theta = (Math.PI / 180) * (360 / segments); //Degrees = radians * (180 / π) for (i =0;i<=segments;i++){ x = Math.cos(theta*i); z = Math.sin(theta*i); cylinderBotVertices.push(x, y, z); //Bottomvertices cylinderBotVertices.push(rbt, gbt, bbt, al); //Color for bottom vertices cylinderSideVertices.push(x, y, z); //Sidevertices along the bottom cylinderSideVertices.push(r,g,b,al); //Vertex color cylinderSideVertices.push(x, y+2, z); //Sidevertices along the top with y = 2 cylinderSideVertices.push(r,g,b,al); //Vertex color cylinderTopVertices.push(x, y+2, z); //Topvertices with y = 2 cylinderTopVertices.push(rbt, gbt, bbt, al); //Color for top vertices } |

Remember that and .

If i = segments and segments = 18, our angle will be 20 and our theta will be . At i = segments = 18 we will get: and we will have gone a full circle. We’ve filled some arrays with vertices, now you just need to draw them!

Take a look at the code here, and the demo here.

Had to go trough multiple sites just to see working example (on a separate page with minimalistic code) of drawing a circle.

Big ty.