## WebGL Basics 6 – Torus-shaped strip

In the previous post we looked at complex mathematical transformations in order to set-up an environment where the observer can turn and move in all directions. This post deals with the creation of a torus object and the way WebGL renders a strip of triangles.

## Introduction

Our test page is now ready for more complex objects. This part 6 is dedicated to:

• The creation (per Javascript code) of a torus composed of one long strip rolled around it
• Some changes in the code to demonstrate different rendering modes and the dynamic control of the object being rendered

The results looks like a ring-shaped spring:

## Torus surface formulas

First of all, we need to determine the coordinates of a point on the surface of the torus. In the previous post we saw the rotation formulas, so we use them again. Namely the torus is defined as a circle in the XZ plane that rotates around the Z axis (r is the radius of the big circle, θ the rotation angle around Z, sr the section radius, α the angle of the point in the section):

We start by defining the coordinates of the point on the section circle centered at (r,0,0) with radius sr (vector on the right hand side) and let it rotate around the Z axis, hence multiply the coordinates by a rotation matrix (see previous post for the formula):

The result of the product gives the coordinates of a point on the surface of the torus:

## Creation of the toroidal strip

The idea here is to compute the coordinates of the points that form a long strip rolled on the surface of the torus. The strip itself is a made of a long broken zigzag line as illustrated hereafter:

By rendering the coordinates as a “`TRIANGLE_STRIP`“, WebGL will then use the points successively 3-by-3 to build a continuous strip of connected triangles.

The formulas giving the successive point coordinates are derived from the previous section, with a tweaked definition of the rotation angles. If we set n to be the number of times the strip is rolled around the torus, and sn the number of triangle pairs on one round of the strip. Then for each round, α goes from 0 to with steps of 2π/sn (every two points, due to the zigzag pattern). θ is continuously incremented during the complete torus computation such that the strip rolls around, θ goes hence from 0 to with a step equal to 2π/sn at each new round, and 2π/(sn*n) at each new zigzag pattern.

Finally, we introduce an interleave factor to control the space between one round of the strip and the next one. It is defined as a multiplication factor of the width of the strip, i.e. an interleave equal to 1 would leave no space between 2 successive rounds of the strip.

## Changes in the code

The function that gives the torus coordinates is as following:

```// Creates a 3D torus in the XY plane, returns the vertices in a Float32Array
// n:  number of faces
// sn: number of faces on section
// k:  factor between 0 and 1 defining the space between strips of the torus
function makeTorus(r, sr, n, sn, k)
{
// Temporary arrays for the vertices and the normals
var tv = new Array();

// Iterates along the big circle and then around a section
for(var i=0;i&amp;lt;n;i++)
for(var j=0;j&amp;lt;sn+1*(i==n-1);j++)
{
// Pre-calculation of angles
var a =  2*Math.PI*(i+j/sn)/n;
var a2 = 2*Math.PI*(i+j/sn+k)/n;
var sa = 2*Math.PI*j/sn;

// Coordinates on the surface of the torus
tv.push((r+sr*Math.cos(sa))*Math.cos(a)); // X
tv.push((r+sr*Math.cos(sa))*Math.sin(a)); // Y
tv.push(sr*Math.sin(sa));                 // Z

// Second vertex to close triangle
tv.push((r+sr*Math.cos(sa))*Math.cos(a2)); // X
tv.push((r+sr*Math.cos(sa))*Math.sin(a2)); // Y
tv.push(sr*Math.sin(sa));                  // Z
}

// Converts and returns array
return new Float32Array(tv);
}
```

The other changes are straightforward. First new controls are created in the HTML part to let the user play with the torus parameters. Second a new function `updateObject` is created, which gathers the code called each time the torus is re-computed:

```// Updates object with global parameters
function updateObject()
{
// ----------- added in part 6 --------------------

// Gets the torus factor from the HTML page
var interleave = parseFloat(document.getElementById('interleave').value);
var numsegs = parseFloat(document.getElementById('numsegs').value);
var numssegs = parseFloat(document.getElementById('numssegs').value);

// Creates the object in &amp;quot;vertices&amp;quot;
vertices = makeTorus(0.7, sradius, numsegs, numssegs, interleave);

// ---------- moved from function start() -----------

var vattrib = gl.getAttribLocation(program, 'ppos');
if(vattrib == -1)
gl.enableVertexAttribArray(vattrib);

// Initializes the vertex buffer and sets it as current one
var vbuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vbuffer);

// Puts vertices to buffer and links it to attribute variable 'ppos'
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
gl.vertexAttribPointer(vattrib, 3, gl.FLOAT, false, 0, 0);
}
```

As usual you can play with the page on-line and experiment different combinations of parameters.

## Summary

The main points to remember:

• A torus has been defined as a sequence of point coordinates according to a zigzag pattern
• WebGL renders these points as a continuous strip of triangles using the mode `TRIANGLE_STRIP` in `drawArrays`
• New controls allow the user to change parameters of the torus, which is re-calculated on-the-fly

Stay tuned for the next part.