¿Cómo sabe la piel de un leopardo dónde poner cada mancha, o la de una cebra dónde va cada raya? En 1952, Alan Turing propuso una respuesta sorprendente: no hace falta ningún plano. Bastan dos sustancias que reaccionan entre sí y se difunden a distinta velocidad para que, a partir de una mezcla casi uniforme, aparezcan solas manchas, rayas y laberintos. Es la reacción-difusión, y aquí puedes verla en marcha y jugar con ella.
Una idea de Turing
Turing es conocido sobre todo por sus trabajos sobre la computación y por descifrar códigos en la Segunda Guerra Mundial, pero uno de sus últimos artículos, The Chemical Basis of Morphogenesis (1952), trataba de biología: de cómo un embrión, que empieza siendo una bola de células casi iguales, desarrolla formas y dibujos. Su idea era que unas sustancias químicas, a las que llamó morfógenos, podían organizarse solas en patrones si se cumplían dos condiciones: que una de ellas se fabricara a sí misma (que fuera autocatalítica) y que las dos se extendieran por el tejido a velocidades distintas.
Durante décadas fue una curiosidad teórica. En 1990, un equipo francés de Burdeos consiguió por primera vez manchas de Turing en un laboratorio, con una reacción química en un gel. Y en 1995, Shigeru Kondo y Rihito Asai mostraron en Nature que las rayas del pez ángel emperador se mueven y se reorganizan a medida que el pez crece, justo como predice el modelo. Hoy se estudia su papel en las rayas del pez cebra, en el reparto de los folículos del pelo y en las huellas dactilares.
Las reglas del juego
El modelo más usado para verlo en un ordenador es el de Gray-Scott, de los químicos Peter Gray y Stephen Scott. Imagina un tablero en el que cada casilla tiene una cantidad de dos sustancias, U y V, y en cada paso pasan cuatro cosas:
Lo importante es el equilibrio entre ellas. V se multiplica allí donde ya hay V (la reacción), pero gasta U, y U llega desde las casillas vecinas más deprisa de lo que V se extiende. Así, una mancha de V crece, agota la U que tiene alrededor y deja un anillo hambriento en el que ninguna otra mancha puede crecer. Ese «yo crezco aquí, tú no puedes crecer al lado» es lo que reparte las manchas a distancias regulares. Todo depende de dos números: F, lo rápido que entra U nueva, y k, lo rápido que se elimina V. Pequeños cambios en ellos dan figuras muy distintas.
Pruébalo
La animación simula el modelo en un tablero de 240 por 160 casillas, cerrado sobre sí mismo: lo que sale por un borde entra por el contrario. Cuanto más oscuro, más V hay. Empieza con unas gotas de V repartidas; elige una receta para ver cada tipo de figura, o toca el tablero para añadir gotas (con el ratón también puedes arrastrar). Los deslizadores cambian F y k sobre la marcha, y puedes ver cómo una figura se transforma en otra. Si te pierdes, «Empezar de nuevo» vuelve a la receta.
0 pasos
Un mapa de figuras
En 1993, John Pearson publicó en Science el artículo Complex Patterns in a Simple System, en el que recorrió con un ordenador cientos de combinaciones de F y k y clasificó las figuras que aparecían. Su hallazgo más llamativo fueron las manchas que se dividen como células: crecen hasta un tamaño crítico, se estiran y se parten en dos, una y otra vez. Estas son las recetas de la animación:
| Receta | F | k | Qué se ve |
|---|---|---|---|
| Manchas | 0.0367 | 0.0649 | Manchas que se dividen hasta llenar el tablero, como un cultivo de células |
| Laberinto | 0.029 | 0.057 | Rayas que se ramifican, como una cebra o una huella dactilar |
| Coral | 0.0545 | 0.062 | Rayas gruesas que crecen por las puntas |
| Agujeros | 0.039 | 0.058 | El negativo de las manchas: huecos redondos en un fondo de V |
| Gusanos | 0.078 | 0.061 | Tiras y anillos sueltos que crecen despacio |
Fuera de una franja estrecha de valores no pasa nada interesante: V desaparece o lo invade todo. Las figuras viven justo en la frontera entre esos dos extremos.
Reacción-difusión en Python
Con numpy, el modelo cabe en unas pocas líneas: np.roll desplaza el tablero entero una casilla para sumar las vecinas de todas las casillas a la vez. El programa empieza con una sola mancha en el centro, con los valores de la receta de las manchas, y cada 3,000 pasos cuenta cuántas hay:
import numpy as np
N = 100 # tablero de 100 × 100 casillas, cerrado sobre sí mismo
F, K = 0.0367, 0.0649 # alimentación y retirada: la zona de las manchas que se dividen
DU, DV = 1.0, 0.5 # V se difunde a la mitad de velocidad que U
def laplaciano(Z):
"""Cuánto se diferencia cada casilla de la media de sus vecinas (lados 0.2, diagonales 0.05)."""
lados = np.roll(Z, 1, 0) + np.roll(Z, -1, 0) + np.roll(Z, 1, 1) + np.roll(Z, -1, 1)
diagonales = sum(np.roll(np.roll(Z, a, 0), b, 1) for a in (1, -1) for b in (1, -1))
return 0.2 * lados + 0.05 * diagonales - Z
def manchas(V):
"""Cuenta las manchas: grupos de casillas con V > 0.2 que se tocan por un lado."""
dentro, vistas, n = V > 0.2, np.zeros_like(V, dtype=bool), 0
for y, x in zip(*np.nonzero(dentro)):
if vistas[y, x]:
continue
n += 1
pila = [(y, x)]
vistas[y, x] = True
while pila:
cy, cx = pila.pop()
for dy, dx in ((1, 0), (-1, 0), (0, 1), (0, -1)):
ny, nx = (cy + dy) % N, (cx + dx) % N
if dentro[ny, nx] and not vistas[ny, nx]:
vistas[ny, nx] = True
pila.append((ny, nx))
return n
U = np.ones((N, N)) # todo lleno de U...
V = np.zeros((N, N)) # ...y nada de V, salvo una mancha cuadrada en el centro
U[45:55, 45:55], V[45:55, 45:55] = 0.5, 0.25
for paso in range(1, 30001):
uvv = U * V * V # la reacción: U + 2V → 3V
U += DU * laplaciano(U) - uvv + F * (1 - U) # entra U nueva
V += DV * laplaciano(V) + uvv - (K + F) * V # sale V
if paso % 3000 == 0:
print(f"Paso {paso:>6}: {manchas(V):>3} manchas")
# Dibujo: más oscuro cuanto más V hay; cada carácter es un bloque de 2 × 4 casillas
for fila in range(0, N, 4):
print("".join(" .:-=+*#%@"[min(9, int(V[fila:fila + 4, col:col + 2].mean() / 0.035))] for col in range(0, N, 2)))salidaPaso 3000: 1 manchas
Paso 6000: 1 manchas
Paso 9000: 1 manchas
Paso 12000: 4 manchas
Paso 15000: 20 manchas
Paso 18000: 32 manchas
Paso 21000: 32 manchas
Paso 24000: 32 manchas
Paso 27000: 32 manchas
Paso 30000: 32 manchas
.:.. :--:. ..:. .=**+: :*%@#=.
-#@@%=. :*@@%=. -%@@@=. -%@@@+.
.-+*=: :*@@%=. :*@@@+. .=**=. . .:==-.
-#@@@+. .::. .:-:. .=#%*-
.=#%*-. :+**-. .... -%@@@=.
.. :+*=: .+@@@#: .=#@%*: .-++-. :+##+:
:*@@@*: :=*+-. .+@@@%- .=@@@%-
.:::. .-*#*=. .-==: .:-:. .=**-.
:*@@%+. .=**=. :*@@@*:
:+@@@+. ... .=@@@%=. .:::. .+%@%+. ..
.:-:. .+%@#=. :=**=. :*@@@+. .:.. .-#%#=.
:#@@@+. :*@@@+. :*@@@#:
:=+=: :-=-. .:::. .:::. .-=-: :=+=:
:#@@@*: .+@@@*: .+@@@#:
.=#%#-. ..:. .+@@@*: .=**=: .=#@%+. .:-:.
.. .+%@%+. .:::. .=%@@@=. ... .+@@@+:
:*@@@*: .=**=. .+%@@*:
.-**=. .:-:. :==-. .=*#*-. .:::.
-%@@@=. -%@@@+. .-+*=: :*@@@*:
:+##+: .-++-. :*%@#=. :#@@@+. :=*+: ..
.=@@@%- .... .-**+: .-*%#=.
-*%#=. .:-:. .::. .+@@@#-
.-==:. . .=**=. .+@@@*: .=%@@*: :=*+-.
.+@@@%- .=@@@%- .=%@@*: .=%@@#-
.=#@%*: :+**=. .:.. .:--: ..:. Durante los primeros 9,000 pasos solo hay una mancha, que crece y cambia de forma. A los 12,000 pasos ya hay cuatro, a los 15,000 hay 20 y a los 18,000, 32. Ahí el tablero está lleno: cada mancha tiene a su alrededor el espacio justo para no estorbar a las demás, y la cuenta ya no cambia. El dibujo final muestra lo que más llama la atención del modelo: las manchas no están puestas al azar, sino a distancias casi iguales, aunque nadie les ha dicho dónde ponerse. Como el estado inicial es siempre el mismo, la salida es idéntica en cada ejecución.
Por qué fascina
Como el juego de la vida o la hormiga de Langton, la reacción-difusión muestra cómo reglas locales muy simples producen orden a gran escala. Pero aquí hay algo más: no es solo un juego matemático, sino una de las explicaciones que usa la biología para entender cómo se forman los dibujos de los seres vivos. Por eso también se usa en informática gráfica para generar texturas naturales, como pieles, cortezas o corales. Y tiene su ironía: el artículo con el que Turing abrió este campo se publicó dos años antes de su muerte, y tardó casi cuarenta en confirmarse en un laboratorio.
Fuentes: A. M. Turing, «The Chemical Basis of Morphogenesis», Philosophical Transactions of the Royal Society B (1952); J. E. Pearson, «Complex Patterns in a Simple System», Science 261 (1993), también en arXiv; V. Castets, E. Dulos, J. Boissonade y P. De Kepper, Physical Review Letters 64 (1990); S. Kondo y R. Asai, «A reaction-diffusion wave on the skin of the marine angelfish Pomacanthus», Nature 376 (1995); el tutorial de Karl Sims, cuyo esquema de cálculo usan la animación y el programa. El programa se ejecutó con Python 3.13 y numpy 2.5.4. La animación y las imágenes, incluida la portada, las genera el propio algoritmo: decodigo.com.
