Алгоритм Flocking / Boids: поле зрения, заданное углом в 3D

#algorithm #math #artificial-intelligence #simulation #angle

#алгоритм #математика #искусственный интеллект #Симуляция #угол

Вопрос:

Я пытаюсь создать алгоритм boids в Unity 3D.

Я столкнулся с одной проблемой: как реализовать поле зрения под определенным углом?

360 градусов — это просто — вы проверяете только расстояние между двумя boids. Но я не хочу, чтобы boids могли смотреть за собой. Я также хочу иметь возможность изменять угол обзора в инспекторе, поэтому он должен основываться на вычислениях.

Я был бы благодарен за любые идеи: (

введите описание изображения здесь
введите описание изображения здесь

Я уже пробовал с сетчатым коллайдером, который является конусом, но у него ничего не получилось. — не работает при 180 и выше. Итак, я ищу лучший способ вычислить это.

Ответ №1:

Предположим, что boid находится в точке p = (p.x, p.y, p.z) , направляющейся к некоторой точке h = (h.x, h.y, h.z) , и мы хотим знать, находится ли объект в точке q = (q.x, q.y, q.z) в поле зрения boid.

Закон косинусов дает нам формулу для косинуса угла φ между направлением движения робота и его траекторией до объекта:

           (h−p) · (q−p)
cos(φ) = ---------------
         ||h−p|| ||q−p||

       = (dx1*dx2   dy1*dy2   dz1*dz2) /
         (sqrt(dx1*dx1   dy1*dy1   dz1*dz1) * sqrt(dx2*dx2   dy2*dy2   dz2*dz2))
 

где

 dx1 = h.x - p.x
dy1 = h.y - p.y
dz1 = h.z - p.z
dx2 = q.x - p.x
dy2 = q.y - p.y
dz2 = q.z - p.z
 

Учитывая некоторый угол ρ (в любых единицах, которые принимает ваша функция косинуса, обычно в радианах), за который боид не может видеть (устанавливая поле зрения ), мы имеем

 φ > ρ  if and only if  cos(φ) < cos(ρ),
 

таким образом, мы можем предварительно вычислить cos(ρ) , а затем использовать приведенную выше формулу для повторных тестов.

Чтобы избежать деления на ноль и других числовых проблем, вы можете проверить, очень ли мал знаменатель деления, и если да, то объявить, что boid может чувствовать любой объект, даже вне его поля зрения.

Комментарии:

1. Здравствуйте, большое вам спасибо за ответ. Однако я не совсем понимаю, как вы получили эту формулу? Я полагал, что закон косинуса соответствует другому уравнению

2. Я разделил по нормам: mathproofs.blogspot.com/2006/07/dot-product-and-cosine.html

3. Большое вам спасибо!

4. @Zearin для переменной, которую вы назвали relTheta , устанавливается значение cos theta, поэтому приведенное p.cos(relTheta) ниже должно быть просто relTheta (которое, вероятно, следует назвать cosRelTheta , чтобы избежать путаницы). Кроме того, p5.Vector.sub(this.velocity, this.position) выглядит подозрительно, если вы имеете в виду скорость в традиционном смысле. h в этом ответе указана точка назначения, и h-p она должна иметь то же направление, что и скорость boid, если она направляется туда.

5. @Zearin нет, вы не должны вызывать cos для частного. Правильное определение const cosRelTheta = numerator / denominator .