En utilisant l’angle dit « angle d’or » (environ 137.5 degrés ou 2.3999 radians), on peut dessiner une spirale de Fermat selon un modèle inventé par H. Vogel, à la manière des étamines des tournesols, des écailles des pommes de pin ou de diverses organisations naturelles.

rayon = c * √n
θ = n * φ
où c est une constante (si on change c, l’espacement qui sépare les éléments de la spirale change), φ est l’angle d’or et n dénombre chaque élément de la spirale. Dans l’exemple qui suit (langage processing), n prend les valeurs successives de n sont 0, 1, 2, 3, 4, et ainsi de suite jusqu’à 1000 ; Le constante c a la valeur de 10 :
float angledor=radians(137.5);
void setup(){
size(400,400);background(255);strokeWeight(7);smooth();
float x=200;float y=200;float constante=10;
for(int a=0;a<1000;a++){
float r=constante*sqrt(a);
x+=cos(angledor*a)*r;y+=sin(angledor*a)*r;
point(x,y);
}
}
On pourrait être encore plus précis en calculant l’angle d’or à la volée. Sa valeur est égale à (2*Π)/φ+1. La valeur de φ, le nombre d’or, est (1+√5)/2.
À la place de float angledor=radians(137.5); on pourra donc écrire :
Julien Quint m’a envoyé une version HTML de la même formule, à laquelle il ajoute de la couleur. Son code repose sur l’objet Canvas :
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Tournesol</title>
<script type="text/javascript">//<![CDATA[
function hsl_to_rgb(h_, s, l)
{
var c = s * (l <= 0.5 ? 2 * l : 2 - 2 * l);
var h = h_ / 60;
var x = c * (1 - Math.abs(h % 2 - 1));
var m = l - c / 2;
h = Math.floor(h);
var r = Math.round(([c, x, 0, 0, x ,c][h] + m) * 255);
var g = Math.round(([x, c, c, x, 0, 0][h] + m) * 255);
var b = Math.round(([0, 0, x, c, c, x][h] + m) * 255);
return "rgb(" + [r, g, b].join(", ") + ")";
}
function draw()
{
var canvas = document.querySelector("canvas");
var context = canvas.getContext("2d");
var angle = 2 * Math.PI / (1 + (1 + Math.sqrt(5)) / 2)
var x = canvas.width / 2;
var y = canvas.height / 2;
var c = 10;
for (var a = 0; a < 1000; ++a) {
var r = c * Math.sqrt(a);
x += Math.cos(angle * a) * r;
y += Math.sin(angle * a) * r;
context.fillStyle = hsl_to_rgb((angle * a / Math.PI * 180) % 360, 1, .5);
context.beginPath();
context.arc(x, y, 3.5, 0, Math.PI * 2, true);
context.fill();
}
}
//]]>
</script>
</head>
<body onload="draw();" style="margin:200px auto 0 auto; width: 400px">
<canvas width="400" height="400"/>
</body>
</html>