01 · Punto de partida
El mundo sin casillas
En el Tema 14 el mundo era una grilla y moverse era saltar de celda en celda. Pero una bandada no salta por baldosas, un peatón no pisa el centro de cada casilla, un auto no dobla en 90°. El espacio continuo guarda posiciones reales (0,37, no celda 3) y deja deslizar con cualquier rumbo y cualquier paso.
Esa libertad da realismo y nueva responsabilidad: la distancia es euclídea, los choques son solapamientos suaves y el paso gigante ya no rebota en una celda sino que atraviesa cuerpos sin registrarlos.
- ¿Con qué precisión se guarda cada posición?
- ¿Qué distancia cuenta como contacto si no hay celdas?
- ¿Qué impide que dos cuerpos se solapen?
- ¿Qué borde frena un desliz sin casillas?
02 · Definición
Posición, distancia y desliz
Todo mundo libre combina tres piezas, del punto al movimiento:
Posición
El par real (x, y) en [0, 1]. Dos agentes pueden estar a 0,001 sin compartir nada: no hay casilla que los iguale.
Distancia
La euclídea con hipotenusa: cerca es número, no celda lindera. Define contactos, contagios y frenos.
Desliz
El vector paso por dirección con cualquier ángulo. El rumbo ya no es cruz: son 360° reales.
| Mundo | Posición | Contacto típico |
|---|---|---|
| Bandada | punto libre en el cielo | separación si dist < cuerpo |
| Multitud | cuerpo con radio | empuje suave, no rebote de celda |
| Tráfico | auto en carril real | frenar por hueco en metros |
| Epidemia | encuentro cercano | contacto si dist < 2 m un rato |
03 · Contraste
Discreto que cuenta frente a continuo que mide
La casilla ordena gratis; el continuo mide exacto pero exige resolver solapamientos. Elegir uno es elegir qué artefacto se acepta.
Espacio discreto
Casillas que ordenan
Saltar es barato y chocar es binario: libre u ocupada. Ideal para butacas, lotes y Vida, pero escalona diagonales y giros.
Espacio continuo
Reales que deslizan
Deslizar es suave y chocar es gradual: si dist < dmin → separar. Ideal para bandadas y multitudes, pero cada par cuesta y el paso manda.
- Coordenada real
- Flotante en rango continuo: 0,37 vale distinto que 0,38. La resolución es infinita hasta que el paso la limita.
- Espacio personal
- Distancia mínima deseada (dmin): por debajo hay incomodidad y empuje. Reemplaza la exclusiva de celda.
- Solapamiento
- Par con distancia menor al cuerpo o al dmin. No es error de mapa: es la señal para separar.
- Paso temporal
- Cuánto avanza por ronda (dt × velocidad). Si supera el cuerpo, atraviesa sin tocar: túnel por paso gigante.
04 · Ciclo
El paso que desliza y separa
Cada ronda integra movimiento y resuelve cercanías, en este orden:
- 1Percibir vecinos reales.
Listar por distancia euclídea dentro del radio (Tema 13), sin celdas.
- 2Deslizar la posición.
Sumar paso por dirección y aplicar borde continuo: muros con tope, toro con módulo (Tema 7).
- 3Separar solapados.
Empujar suave a quienes quedaron bajo el espacio personal, antes de decidir el próximo giro.
05 · Representación en Python
Flotantes que se empujan suave
La posición es par de flotantes. Moverse es trigonometría con borde; separar es empujar a lo largo del vector que los une.
Python en tu navegador. Cambiá el espacio personal y observá cuándo dos puntos empiezan a molestarse.
import math
class Agente:
def __init__(self, x=0.5, y=0.5, rumbo=0.0):
self.x, self.y, self.rumbo = x, y, rumbo
def deslizar(self, paso=0.03, borde="muros"):
nx = self.x + paso * math.cos(self.rumbo)
ny = self.y + paso * math.sin(self.rumbo)
if borde == "toro":
self.x, self.y = nx % 1.0, ny % 1.0
else:
self.x, self.y = min(1.0, max(0.0, nx)), min(1.0, max(0.0, ny))
return (self.x, self.y)
a = Agente(0.95, 0.5, rumbo=0.0)
print(a.deslizar(paso=0.1, borde="muros"))
print(a.deslizar(paso=0.1, borde="toro"))
Con muros queda en 1,0; en toro reaparece por 0,05: el mismo desliz, otro borde continuo.
Separar sin celdas
Si la distancia cae bajo el mínimo, cada uno retrocede la mitad del solape.
def separar(a, b, dmin=0.05):
dx, dy = b.x - a.x, b.y - a.y
d = math.hypot(dx, dy)
if d == 0 or d >= dmin:
return False
empuje = (dmin - d) / 2
ux, uy = dx / d, dy / d
a.x -= empuje * ux; a.y -= empuje * uy
b.x += empuje * ux; b.y += empuje * uy
return True
a, b = Agente(0.5, 0.5), Agente(0.52, 0.5)
print(separar(a, b), round(math.hypot(b.x - a.x, b.y - a.y), 3))
06 · Exploración
Laboratorio: espacio personal en desliz libre
Los agentes deslizan al azar con paso fijo 0,03. El círculo pálido es su espacio personal: si dos círculos se tocan hay roce y el modelo los cuenta. Las líneas rojas son roces de este paso. Ajustá el espacio y observá cuándo la libertad se vuelve multitud.
Libres pero no amontonados
si dist < dmin → roce
Con 40 agentes y espacio 0,05, los roces son ocasionales.
Cada punto desliza libre sin casillas; el halo es su espacio personal. Las líneas rojas marcan pares en roce. Pulsá Nueva réplica para otra caminata con los mismos parámetros.
Preguntas para explorar
- Con espacio 0 y 80 rondas, ¿cuántos roces hay? ¿Por qué sin dmin no hay roce aunque se pisen?
- Subí el espacio al máximo con 100 agentes. ¿Qué le pasa al vecino medio y a la cobertura?
- Repetí la misma configuración 3 veces. ¿Los roces son idénticos? ¿Qué parte es desliz y qué parte es encuentro?
Ver respuestas sugeridas
- Cero: sin umbral no hay criterio de contacto. El continuo mide, pero el roce lo define el dmin declarado.
- El vecino medio se achica en términos relativos y los roces se disparan; la cobertura apenas cambia porque el mapa es el mismo: más exigencia, misma superficie.
- No: la caminata arma encuentros distintos. El desliz con paso fijo es la regla; la historia de cercanías no.
07 · Comprensión
Confusiones frecuentes
«Continuo es discreto con celdas chicas»
Celdas chicas siguen saltando por centros y rebotando en binario. Continuo es flotante con distancia euclídea y empuje gradual.
«Sin celdas no hay choques»
Hay roces por distancia: si dist < dmin se separan. Sin esa regla los cuerpos se atraviesan como fantasmas.
«El paso grande cubre más y listo»
El paso mayor que el cuerpo tuneliza: cruza sin registrar contacto ni contagio. Continuo exige paso chico frente a cuerpo.
«Vecinos por radio sale gratis»
Cada par cuesta: N agentes son N² distancias por paso. Sin grillas espaciales ni topes, el continuo no escala (Temas 46–47).
08 · Práctica guiada
Ejercicios con Python
Ejercicio 1: medir en vez de contar
Ejecutá y verificá la distancia real. Luego mové el segundo a (0.6, 0.8) y comprobá que la celda habría dicho lo mismo.
import math
print(round(math.hypot(0.6 - 0.5, 0.8 - 0.5), 3))
Ver solución razonada
Da 0,316: lejos en continuo aunque caigan en celdas vecinas. La celda iguala; el flotante distingue.
Ejercicio 2: predecir el túnel
Sin ejecutar primero: cuerpo 0,04 y paso 0,10. ¿Puede cruzar a otro sin tocarlo? Comprobalo con dos posiciones.
x0, x1, otro = 0.40, 0.50, 0.45
print("salta por encima:", abs(x1 - otro) < 0.04 or abs(x0 - otro) < 0.04)
Ver solución
Registra False en ambos extremos aunque pasó por 0,45: el salto tunelizó el contacto. Paso chico o chequeo intermedio lo evita.
Ejercicio 3: roce que separa
Dos agentes a 0,03 con dmin 0,05. ¿Hay roce y a qué distancia quedan tras separar?
Ver una posible respuesta
import math
a, b, dmin = [0.5, 0.5], [0.53, 0.5], 0.05
d = math.hypot(b[0]-a[0], b[1]-a[1])
print(d < dmin, round(dmin, 3))
Hay roce (True) y quedan a 0,05: el empuje reparte el solape. Sin separar, el próximo paso decide sobre cuerpos pisados.
09 · Síntesis
Ideas para recordar
- Continuo es posición real, distancia euclídea y desliz con cualquier rumbo.
- El contacto es roce por dmin con empuje suave, no celda libre u ocupada.
- El paso debe ser chico frente al cuerpo: si no, tuneliza encuentros.
- El borde continuo se declara (muros con tope, toro con módulo) como en discreto.
- En Python, deslizar suma vector y separar reparte el solape a lo largo del eje.
En el próximo tema estudiaremos la actualización síncrona: todos los agentes cambian a la vez.