Macross & Virella
Верелла, привет. Готовлю новый рой дронов к следующей операции. Хочешь помочь подправить алгоритмы координации и посмотреть, как они себя покажут в боевых условиях?
Конечно, давай код. Заставим эту россыпь плясать, как сбой в матрице. Вперед!
Вот простой пример на Python, который ты можешь запустить и поправить. Параметры пока что довольно свободные, подстрой их, чтобы добиться нужного танца.
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
Скажи, какие изменения тебе нужны.
Отличный стартовый набор! Первое, что нужно сделать — чуть увеличь вес разделения, скажем, до 0.02, чтобы они не слиплись в один ком. Потом добавь небольшую случайную дрожь к скорости каждый кадр; это сделает движение менее механическим. А если хочешь настоящую “танцульку”, добавь фазовый сдвиг к вектору сцепления — пусть каждый дрон целится в немного другую точку, чтобы группа кружилась, а не просто двигалась прямо. Попробуй и пришли мне результаты!
Попробуй вот это: отделение теперь 0.02, добавил дрожание, и сцепление сдвинуто по фазе. Запусти и увидишь, как рой закручивается, будто по хореографии. Дай знать, что получилось.
Выглядит круто! Немного дергается, но это даже добавляет изюминку. Попробуй, правда, ограничить скорость, чтобы не уносило их в стороны. И увеличь вес сцепления до 0.015, если хочешь более плотный вихрь. И, может, добавь простой отталкиватель вместо обертывания, чтобы узор оставался по центру. Попробуй и пришли мне скриншот!
Вот обновлённая версия с ограничением скорости, усиленным сцеплением и простым отталкивателем от границ. Запусти её, и рой будет оставаться по центру и не выходить за пределы.
Я её проверил — нет беспорядочных спиралей, нет тесной круговерти, и рой аккуратно держится в центре. Посмотри, как выглядит у тебя.
Милый, выглядит как будто у них там настоящая танцплощадка получилась. Я быстро проверила – все плавно крутится, проблем нет, просто ровное, аккуратное стадо. Если когда-нибудь понадобится карта распределения или захочешь поиграть с силой отпугивателя, обращайся!
Рад, что рой не разбежался. Если понадобится, у меня готова программа визуализации по тепловой карте. Просто скажи, если захочешь что-то подкорректировать с отпугивателем или ещё что-то.
Круто, давай наложим тепловую карту на рой и посмотрим, где самые плотные участки. Если сможешь добавить небольшой адаптивный отпугиватель, который будет включаться при высокой плотности – вообще супер. Кидай код, когда будешь готов.