Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / HTML

Dancing with Spirals

5.00/5 (15 votes)
2 Nov 2017CPOL12 min read 21.1K   393  
Understanding and using technique of generating and plotting spirals in plain JavaScript. Offering web-pages demonstrating different kind of spirals.

Introduction

Spirals are amazing images that have been known for centuries. They are really ubiquitous and could be found in nature (from sea shells and plants to galaxies), in arts and machinery (from tiny wrist watches to big trucks and trains), etc.

Here is a simple definition from Wikipedia [1]:

"In mathematics, a spiral is a curve which emanates from a point, moving farther away as it revolves around the point."


Here is another handy definition from Rosetta Code Wiki (RC) [2]:

"A Polyspiral is a spiral made of multiple line segments, whereby each segment is larger (or smaller) than the previous one by a given amount. Each segment also changes direction at a given angle."

It should be stressed, there are tons of spiral samples in dozens of languages, including in the JavaScript. Just search the Internet for particular type of spiral you are interested in.

Some of the most significant types of two-dimensional spirals include: Archimedean spiral [1], Polyspiral [2] and Vogel spiral [3,4]. But it depends upon the opinion of the researcher, i.e., what is so significant? We are not conducting any kind of research here, we just practicing "dancing" with spirals. Occasionally, some properties would be mentioned or stressed, just for better understanding.

The goal of this article is to prove that even newbie in coding can start spiraling in JavaScript.

Because this article is targeting the beginner coder, - a very simple and understandable code blocks (as the one shown below for Archimedean spiral) are used mostly. Exceptions will be clear marked later.

This project is offering to the beginner or intermediate developer the set of project components as a desktop generators of unlimited number of pretty simple (not fancy) spirals. All 3 important types of spirals (mentioned above) are covered.

Developer should look through source code of project files to become self-educated. Only a few prime fragments would be discussed briefly, because there is only a very simple math used and simple, short and clear functions employed. So, learn spiraling by examples.

Any user can use this project software as a desktop application. Just download it and start using.

Only 3 HTML pages and 1 JavaScript file are presenting a whole very compact source code you need to start "dancing" with spirals. Everyone with a computer already has a reliable tool able to do it: this is the browser, and the only requirement for it is to support "canvas" object.

Common technique to generate and plot spirals

Any function generating spirals has a typical structure, which is reflecting the fact that using the polar coordinate system [5] is more appropriate for any spiral description. So, in polar coordinates most spirals (and other figures) having unique equation/function like following: r = f(theta), where the radius r is a monotonic continuous function of angle theta.

The polar coordinates r and theta can be converted to the Cartesian coordinates x and y as following [5]: x=r*cos(theta) and y=r*sin(theta). Note: in the fragments below t is used instead of theta.

Remarks:

  • Two prime sources for typical polar spiral functions are [1,6]. Sometimes, the same named plotted spirals from different sources could be looking differently. Not to mention when one or two additional coefficients or functions are applied.
  • In addition, a few unique functions were found, and they are all referenced.
  • Yes! I've found all functions on the Internet, but in almost all cases they were simplified and unified (sometimes rebuilt) to fit shown above typical function.

 

The following JavaScript fragment shows how Archimedean spiral is generating and plotting using lines. Note: a code fragment setting global variables is attached in the beginning of the Archimedean spiral function for clarity.

JavaScript
// GLOBAL VARS
var cvs, ctx, cw, c; // canvas, context, canvas width and center
var clr; //color
var pm, st, it, n, a, b; // init pars: pm - plot mode, st - spiral type,
                         // it - init angle, n - dots, a,b - coefficients.
var r, t, x, y;          // radius, theta angle, coordinates.
var pi=Math.PI, pi2=pi*2, pi3=pi/360, snm, h3;
// ******************************************
// *** The Archimedean Spiral #1 c-w (clockwise) ***
function pspArchi1() {
  snm="The Archimedean Spiral #1"; console.log(snm); h3.innerText=snm;
  if (pm=="d") {it=pi3; n=6000; a=2; b=5; c=320;}
  console.log("PARs:", it, "/", n, "/", a, "/", b, "/", c);
  ctx.beginPath(); // creating Path for lines
  for(var i=0; i<n; i++) {
    t=it*i; r=a+b*t;  // calculating theta and radius, and coodinates (below)
    x = r*Math.cos(t) + c; y = r*Math.sin(t) + c; // calculating x and y
    //if (i<5) {console.log("t,r,x,y:", t, "/",  r, "/",x, "/", y)} // 4 test
    //if (i>n-5) {console.log("t,r,x,y:", t, "/",  r, "/", x, "/", y)}
    ctx.lineTo(x, y); // saving line in the Path
  }//fend i
  ctx.stroke(); // plotting saved in the Path lines
}//func end

 

 

As you can see, function is a pretty simple, just 12 lines of code.

Here is the first very simple exercise for you newbie:

EX#1. Create HTML page generating and plotting only "The Archimedean Spiral #1".
You need to wrap JavaScript fragment shown above in HTML tags (before and after it). Also, add default values to all unassigned variables. E.g., clr="navy"; pm="d", etc.


If you are not a total beginner it should take less then 10 minutes for you. If more then it's not a problem. Just keep practicing. Such kind of simple pages (for one figure only) is a good tool for testing new figures.

Let's go back to spirals.

Only 3 things are defining the unique image and type of the spiral:

  • Two essential coefficients: it - initial theta angle and n - number of dots/lines. They are defining both the image and the size of the spiral.
  • Unique polar function: r=f(t). This function could be defined using additional coefficients, e.g., a, b, c, etc. Also, another functions could be used within this one. A polar function is defining the type (means: mostly typical image) of the spiral.

 

In some cases those 2 essential coefficients do not change the type of spiral, but in others, - spiral can be transformed to another type, or even degrade to the single line. You will find this during testing.

Remarks:

  • This type of functions with a similar loop inside is used mostly. But in many cases you need to improvise, especially if spiral has 2 symmetrical branches. E.g., Euler, Fermat, etc. So, formulas and loops are different or they were fixed, simplified, etc.
  • In the Table 1 below many important details are skipped. See page code for them.
  • You are welcome to play with code of any page in project, but remember to have archived copies.

 

The Table 1 below contains almost all used formulas for the first 17 spirals. Note: i) Prefix "Math." was deleted. ii) "Reg." marks regular functions; "Diff." marks unique functions. iii) Find code for spiral "Super 2" in the "Spiral Generator" page.
 

Table 1. Spirals and formulas
Spiral Line 1 Line 2 Notes
Archimedean 1 t=it*i; r=a+b*t; x=r*cos(t)+c; y=r*sin(t)+c; Reg.
Archimedean 2 t=it*i; r=a+b*t; y=r*cos(t)+c; x=r*sin(t)+c; Reg.
Euler t+=dt; //dt=it/n; x+=cos(t*t)*dt; y+=sin(t*t)*dt; Diff.
Fermat t=it*i; r=a*sqrt(t); x=r*cos(t)+c; y=r*sin(t)+c; 2 parts
Hyperbolic t=it*i; r=a/t; x=r*cos(t)+c; y=r*sin(t)+c; Reg.
Lituus t=it*i; r=sqrt(a/t); x=r*cos(t)+c; y=r*sin(t)+c; Reg.
Logarithmic t=it*i*10; r=a*(exp(b*t)); x=r*cos(t)+c; y=r*sin(t)+c; Reg.
Theodorus t=it*i; r=sqrt(i); x=sc*r*cos(t)+c; y=sc*r*sin(t)+c; Diff.
Fibonacci t=it*i; r=(pow(gm,i)-pow(gn,i))/sq5; x=a*r*cos(t)+c; y=a*r*sin(t)+c; Diff.
Involute t=it*i; r=a; x=r*(cos(t)+t*sin(t))+c; y=r*(sin(t)-t*cos(t))+c; Diff.
Super t=it*i; r=c*sqrt(i/n); x=r*cos(t)+c; y=r*sin(t)+c; Reg.
Atomic t=it*i*10; r=t/(t-a); x=sc*r*cos(t)+c; y=sc*r*sin(t) + c; Reg.
Atzema t=i; x=sin(t)/t-2*cos(t)-t*sin(t)+c; y=-cos(t)/t-2*sin(t)+t*cos(t)+c; Diff.
Vogel t=it*i; r=sqrt(i)/sqrt(n); x=sc*r*cos(t)+c; y=sc*r*sin(t)+ c; Diff.
Cochleoid t=it*i*10; r=sin(t)/t; x=sc*r*cos(t)+c; y=sc*r*sin(t)+c; Reg.
Sacks sqi=sqrt(i) x=a*-cos(sqi*pi2)*sqi+c; y=a*sin(sqi*pi2)*sqi+c; Diff.

This table allows to see instantly the differences between prime parts of codes of spirals.

Using the pages

Using the "Spiral Generator" page

 

It is recommended to start with the "Spiral Generator" page, which is the prime part of our "dancing" and has the educational purpose too. You can play with different spiral types, colors and other parameters or just iterate through all types using default parameters.

Note: default parameters were selected to fit nicely the canvas, also, to show the most typical picture of the particular spiral. Default values are highly recommended to start with.

  Figure 4: Two modes of the "Spiral Generator" page (shown partially)  

SG (default values)     SG (input values)

In the drop-down list of this page the first 9 spirals are well known [1], but the others were "discovered" from [6] and other sources [7-11].

See it for yourself: The family of polar spirals in the figures below. Each figure has 8 spirals plotted using polar functions from [1].

  Figure 1: The first 8 spirals are from [1]: Archimedean, Euler, Fermat, Hyperbolic, Lituus, Logarithmic, Theodorus and Fibonacci.  

The Archimedean spiral #1 The Euler spiral The Fermat spiral The Hyperbolic spiral

The Lituus spiral The Logarithmic spiral The Theodorus spiral The Fibonacci spiral

TIP: Right click on any spiral to save it as an image with original 640x640 size. Choose the "png" type to match the original type.

 

  Figure 2: Involute, Super, of change, Atomic, Atzema, Vogel, Cochleoid, Sacks and Super 2 spirals.  

 

The Involute of a circle spiral The Super spiral The Atomic spiral The Atzema spiral

The Vogel spiral The Cochleoid spiral The Sacks spiral The Super 2 spiral

In the Figure 2 above Involute spiral is from [1]. Others are mostly from [6], except for Vogel [3,4] and Sacks [11] spirals.

The 2nd, 4th, 7th and 8th spirals are actually a polyspirals, but it will be discussed briefly later.

The fifth spiral usually is named as "sunflower seeds/florets" spiral. It has many visible clockwise and counter clockwise spiral arms.

Here is the second pretty simple exercise for you beginner:

EX#2. Modify created before page this way: i) find "Big round Dot" function (in source files) and add it to the script; ii) change plotting line function to using added one; iii) Play with "it", "n", etc., to plot nice Archimedean spiral using big dots.

Using the "Polyspirals' Family Generator" page

 

The "Polyspirals' Family Generator" page is pretty simple. It allows user to select the following parameters: color, direction, scale, number of dots and range. Last 3 parameters control the size of plotted polispiral. In addition, "range" is acting as a style changing parameter.

The JavaScript fragment shown below demonstrates how polyspiral is generating and plotting using lines.

JavaScript
// rng - range, sc - scale, cc - canvas center
var it=Math.PI*rng/cc, t, x, y; // it - init theta, t - theta.
for(var i=0; i<n; i++) {
  t=it*i;
  x = sc*t*Math.cos(d*t)+cc; y = sc*t*Math.sin(d*t)+cc;
  ctx.lineTo(x, y);
}//fend i

Note: r is not calculated here! Angle t has the same formula, but it is different. Also, for coordinates x,y a little bit different formula is used. See gnuplot and JavaScript versions on Rosetta Code Wiki [2]

This page is a good tool for conducting research about spirals in general and polyspirals in particular. But again, any research or applications are not even a part of the goal of this article.

What is really interesting: changing only one parameter "range" user can plot amazing variety of spirals! Thousands differently looking spirals.

The Figure 3 below presents 4 polyspirals with triangular, square, pentagon and star patterns.

  Figure 3: Polyspirals with triangular, square, pentagon and star patterns,  

Polyspiral (triangular pattern) Polyspiral (square pattern) Polyspiral (pentagon pattern) Polyspiral (star pattern)

Did you notice that Super spiral in Figure 2 looks identical to the second spiral in Figure 3? They both are polyspirals, although employed different formulas. But we will not discuss this issue here. Just note that one type of a spiral can be transformed to another for some unique combination of coefficients [4].

We are dancing with spirals here, but, in turn, polyspirals show us their own sliding dancing steps (see Figure 3 above):

  • Sometimes they are walking straight lines with turns: "square dancing", "dancing with stars", etc.
  • Or sometimes they are stepping from the left to the right (and vise versa) leaving shorter dancing line segments (pentagon pattern above).
  • Or sometimes they are jumping from the left to the right (and vise versa) overlapping other dancing line segments (triangular pattern above).

 

Not convinced yet? To see many of the different "dancing steps" you need to test this page. Use samples provided in the Table 2 below, which has only selected/tested spiral parameters. It would be fun to try at least some of them, and not only for a beginner.

Table 2. Testing samples
Scale Dots Range(s) Notes
2 100 80 8-gon pattern
2 100 160,480,800,1120 square pattern
2 100 210,430,850,1070 triangular pattern
2 100 240 star pattern (sc=1.2)
2 100 280,300, 310 star pattern (sc=1.2)
2 100 320,640,960 just a line
2 100 330--400,880--950,970--1060,1080--1110 star pattern (sc=1.2)
0.4 100 770 pentagon pattern

Using the "Ulam spiral" page

The Ulam spiral is included as a sample of a little bit more complicated spiral. Plus, it was already many times tested in PARY/GP and R [12].

This is the only spiral here that requires the different generating and plotting technique. You can find plotting helper functions in included VOE.js (v.2.0.).

On this page user can pick one of 3 plot/print styles (using default n and sc values):

  • Plot (n=100; sc=3).
  • Plot and print using asterisks (n=10; sc=5).
  • Plot and print using numbers (n=10; sc=5).

 

Note: Find "printed" spirals in console (Chrome).

Samples of the "printed" Ulam spiral using asterisks and numbers are shown below.

|                    |  |                               |
|           *   *    |  |                61    59       |
|     *           *  |  |       37                31    |
|   *   *       *    |  |    67    17          13       |
|         *   *   *  |  |              5     3    29    |
|       *     * *   *|  |          19        2 11    53 |
|     *   *          |  |       41     7                |
|   *       *        |  |    71          23             |
|     *       *      |  |       43          47          |
|   *           *    |  |    73                79       |

 

Conclusion

 

Although you are a beginner, now, you have a few dozens of polar functions plotting different spirals. I would suggest you the following exersize:

EX#3. Try to "invent" your own spiral (may be even new one, never seen before). You need to create really new function r = f(theta), etc. It's all described in the beginning. Plus, you have already a simple page for it. (I hope...)

Do not cheat, i.e., do not use [6] or other sources. I asked you to "invent" your own spiral, and this is not too hard. Remember the Archimedean spiral you have already modified? It had just 12 lines of script code, but you need to change only 2 lines!

Theoretical and practical uses can be found online. The goal is to demonstrate that nothing difficult or magical is in plotting 2D spirals. Also, to show a few simple approaches to handling options on the HTML page, using canvas, plotting spirals with dots, big dots and lines, utilizing helper functions, etc.

It should be emphasized again, there are tons of spiral samples in many languages, including JavaScript [2,7,12].

Finally, I'm hoping that even beginner coder could be the designer, inventor and creator of amazing new spirals.

References

  1. Spiral, Wikipedia, the free encyclopedia, URL: https://en.wikipedia.org/wiki/Spiral.
  2. Polyspiral, Rosetta Code Wiki, URL: http://rosettacode.org/wiki/Polyspiral.
  3. Vogel, H (1979). A better way to construct the sunflower head. Mathematical Biosciences. 44 (44): pp. 179-189. doi:10.1016/0025-5564(79)90080-4.
  4. Prusinkiewicz, P.; Lindenmayer, A. (1990). The Algorithmic Beauty of Plants. Springer-Verlag. pp. 101-107. ISBN 978-0-387-97297-8.
  5. Polar coordinate system, Wikipedia, the free encyclopedia, URL: https://en.wikipedia.org/wiki/Polar_coordinate_system.
  6. Wassenaar J. Mathematical curves, URL: http://www.2dcurves.com/spiral/spiral.html
  7. Archimedean spiral, Rosetta Code Wiki, URL: http://rosettacode.org/wiki/Archimedean_spiral.
  8. Fermat's_spiral, Wikipedia, the free encyclopedia, URL: https://en.wikipedia.org/wiki/Fermat%27s_spiral.
  9. Super Spiral, Khan Academy, URL: https://www.khanacademy.org/computer-programming/super-spiral/823021393.
  10. Spiral of change, Khan Academy, URL: https://www.khanacademy.org/computer-programming/spiral-of-change/1144297869
  11. Sacks spiral, URL: http://www.dcs.gla.ac.uk/~jhw/spirals/.
  12. Ulam spiral (for primes), Rosetta Code Wiki, URL: http://rosettacode.org/wiki/Ulam_spiral_(for_primes).

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)