Macross & Virella
Hey Virella, I’ve been planning a new drone swarm for the next operation. Want to help tweak the coordination algorithms and see how they perform under pressure?
Absolutely, hit me with the code and let’s make that swarm dance like a glitch in the matrix. Bring it on!
Here’s a basic Python example you can run and tweak. The weights are loose; adjust them to get the dance you want.
import math
import random
class Drone:
def __init__(self, x, y):
self.pos = [x, y]
self.vel = [random.uniform(-1, 1), random.uniform(-1, 1)]
def update(self, drones):
sep = self.separate(drones)
coh = self.cohesion(drones)
ali = self.alignment(drones)
# combine
for i in range(2):
self.vel[i] += 0.01 * sep[i] + 0.01 * coh[i] + 0.01 * ali[i]
self.pos[i] += self.vel[i]
# simple boundary wrap
self.pos[0] %= 100
self.pos[1] %= 100
def separate(self, drones):
steer = [0, 0]
count = 0
for d in drones:
if d is self: continue
dist = math.hypot(self.pos[0] - d.pos[0], self.pos[1] - d.pos[1])
if dist < 10 and dist > 0:
steer[0] += self.pos[0] - d.pos[0]
steer[1] += self.pos[1] - d.pos[1]
count += 1
if count:
steer[0] /= count
steer[1] /= count
return steer
def cohesion(self, drones):
center = [0, 0]
count = 0
for d in drones:
if d is self: continue
center[0] += d.pos[0]
center[1] += d.pos[1]
count += 1
if count:
center[0] /= count
center[1] /= count
return [center[0] - self.pos[0], center[1] - self.pos[1]]
return [0, 0]
def alignment(self, drones):
avg_vel = [0, 0]
count = 0
for d in drones:
if d is self: continue
avg_vel[0] += d.vel[0]
avg_vel[1] += d.vel[1]
count += 1
if count:
avg_vel[0] /= count
avg_vel[1] /= count
return [avg_vel[0] - self.vel[0], avg_vel[1] - self.vel[1]]
return [0, 0]
def simulate(n=50, steps=200):
drones = [Drone(random.uniform(0, 100), random.uniform(0, 100)) for _ in range(n)]
for _ in range(steps):
for d in drones:
d.update(drones)
# log or render positions
Let me know what tweaks you need.
Nice starter kit! First thing—boost the separation weight to a bit higher, say 0.02, so they don’t turn into a sticky‑ball. Then throw in a small random jitter to the velocity each tick; that keeps the pattern from looking too “robotic.” And if you want a true “dance,” add a phase offset to the cohesion vector—make each drone target a slightly different point so the group swirls instead of just moving straight. Give it a whirl and send me the results!
Here’s the quick tweak—separation now 0.02, jitter added, and cohesion gets a phase offset. Give it a run and you’ll see the swarm swirling like a choreographed ripple.
import math, random
class Drone:
def __init__(self, x, y, phase):
self.pos = [x, y]
self.vel = [random.uniform(-1, 1), random.uniform(-1, 1)]
self.phase = phase # unique phase for each drone
def update(self, drones):
sep = self.separate(drones)
coh = self.cohesion(drones)
ali = self.alignment(drones)
# combine with new weights
for i in range(2):
self.vel[i] += 0.02 * sep[i] + 0.01 * coh[i] + 0.01 * ali[i]
# small random jitter
self.vel[i] += random.uniform(-0.05, 0.05)
self.pos[i] += self.vel[i]
self.pos[0] %= 100
self.pos[1] %= 100
def separate(self, drones):
steer = [0, 0]
count = 0
for d in drones:
if d is self: continue
dist = math.hypot(self.pos[0]-d.pos[0], self.pos[1]-d.pos[1])
if dist < 10 and dist > 0:
steer[0] += self.pos[0]-d.pos[0]
steer[1] += self.pos[1]-d.pos[1]
count += 1
if count:
steer[0] /= count; steer[1] /= count
return steer
def cohesion(self, drones):
center = [0, 0]
count = 0
for d in drones:
if d is self: continue
center[0] += d.pos[0]
center[1] += d.pos[1]
count += 1
if count:
center[0] /= count; center[1] /= count
# phase offset for a swirl
angle = self.phase
target = [center[0] + 5*math.cos(angle), center[1] + 5*math.sin(angle)]
return [target[0]-self.pos[0], target[1]-self.pos[1]]
return [0, 0]
def alignment(self, drones):
avg_vel = [0, 0]
count = 0
for d in drones:
if d is self: continue
avg_vel[0] += d.vel[0]
avg_vel[1] += d.vel[1]
count += 1
if count:
avg_vel[0] /= count; avg_vel[1] /= count
return [avg_vel[0]-self.vel[0], avg_vel[1]-self.vel[1]]
return [0, 0]
def simulate(n=50, steps=200):
drones = [Drone(random.uniform(0,100), random.uniform(0,100), random.uniform(0,2*math.pi)) for _ in range(n)]
for _ in range(steps):
for d in drones:
d.update(drones)
# log or render positions
Run it and you’ll see a fluid, dancing pattern instead of a straight line. Let me know how it looks.