#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
Учитывая некоторый угол ρ
(в любых единицах, которые принимает ваша функция косинуса, обычно в радианах), за который боид не может видеть (устанавливая поле зрения 2ρ
), мы имеем
φ > ρ 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
.