Espirògraf

Infotaula jocEspirògraf
Tipusjoguina Modifica el valor a Wikidata
Data de creació1965 Modifica el valor a Wikidata

L'espirògraf és una joguina de dibuix geomètric que permet traçar corbes matemàtiques estil ruleta, tècnicament conegudes com a hipotrocoide i epitrocoide. Va ser desenvolupat per l'enginyer britànic Denys Fisher i venut per primera vegada el 1965.

En computació, la idea es pot ampliar de forma recursiva per generar un espirògraf fractal, on el cercle generatiu actua a la vegada de cercle directiu d'un de més petit, i així successivament generant cada vegada més detall en el traç final d'una manera similar a les sèries de Fourier complexes. Dit d'una altra manera, un espirògraf bàsic de dos cercles (l'immòbil, anomenat directiu, i el que fa la rotació, anomenat generatiu) es pot considerar el cas més simple d'una família de corbes trocoides.

Dibuixant amb espirògraf

Base matemàtica

Es necessiten definir varis de paràmetres per construir un espirògraf; el nombre total de cercles directius (n), la ratio entre els radis dels diferents cercles (m), la ratio entre la velocitat de gir dels diferents cercles (k), i la distància de cada cercle (d) respecte el centre de l'anterior.

El radi del cercle actual es calcula utilitzant la ratio descrita, .

La distància del cercle actual respecte el centre es calcula tenint en compte el radi del cercle anterior i el del cercle actual, , aplicant la suma en el cas de l'epitrocoide i la resta en el de l'hipotrocoide.

La velocitat de gir es calcula partint de la velocitat de gir del cercle anterior i aplicant una ratio constant. Aquesta ratio és gairebé sempre negativa, és a dir, la direcció de rotació va alternant-se a cada cercle.

La fórmula més bàsica seria . Aquesta velocitat és la que s'utilitza per actualitzar l'angle .

Obtenim la posició de cada cercle:

Aquesta posició de l'últim cercle serà la utilitzada per aplicar el traçat final de l'espirògraf.

Exemple en pseudocodi:

// Definir els paràmetres necessaris
n = 11
r_ratio = 3
d_prev = 0.5
d_current = 0.5
k = -4

// Crear el cercle inicial
ary orbits = []
circle = Circle.new(size) // Mida del cercle immòbil
// Emmagatzemar tota la informació necessària del cercle
orbit = Orbit.new(circle, d=0, angle=0, speed=1)
orbits.push(o)

// Crear cadascun dels cercles partint de l'anterior
for i in 1...n
 prev = orbits[i - 1]
 size = previous.circle.size / r_ratio
 circle = Circle.new(size)
 circle.x = prev.circle.x
 circle.y = prev.circle.y
 d = previous.ciecle.size * d_prev + circle.size * d_current
 angle = previous.angle
 speed = previous.speed * k
 orbit = Orbit.new(circle, d, angle, speed)
 orbits.push(orbit)
end

// Actualitzar el dibuix canviant l'angle constantment
loop do
 // Actualitzar la posició de cada cercle
 Graphics.update
 for i in 1...orbits.size
 prev = orbits[i - 1]
 orbit = orbits[i]
 orbit.angle += orbit.speed
 d = orbit.distance
 dx = prev.circle.x + d * Math.sin(angle)
 dy = prev.circle.y + d * Math.cos(angle)
 end
 // Traçar el dibuix
 last = orbits[-1].circle
 if (last_drawn != NULL)
 sx = last_drawn.x
 sy = last_drawn.y
 draw_line(sx, sy, last.x, last.y)
 else
 set_pixel(last.x, last.y)
 end
 last_drawn = Point.new(last.x, last.y)
end

Bibliografia

  • Maurer, Peter M. «A Rose is a Rose...». The American Mathematical Monthly, 94, 7, 1987, pàg. 631-645 [Consulta: 24 octubre 2021].

Enllaços externs