Случайный вектор в полусфере в пределах заданного угла (наиболее оптимальный алгоритм)
При трассировке лучей нередко возникает необходимость генерировать случайный вектор в пределах полусферы, отклоненный от исходного на какой-то заданный угол. На просторах интернета не нашлось внятных и развернутых ответов на данный вопрос. Хоть в математике я не шибко силен, все же хотелось бы понимать что происходит, а не просто брать готовую формулу.
Еще раз вкратце о сути задачи:
Есть какой-то вектор, есть какой-то угол (обычно в таких ситуациях его называют телесным углом, но могу ошибаться), необходимо выбрать какой-то случайный вектор, который находился бы в пределах этого самого угла. Угол может быть все 180 градусов, и охватывать всю полусферу.
Понимаю, что задача стара как мир, но все же, хотелось бы, чтобы кто-то разжевал тупому гуманитарию как это правильно делается. Причем можно привести наиболее оптимальный с точки зрения математики пример, а также пример наиболее оптимальный с точки зрения кода. Нередко они разнятся. Спасибо.
Ответы (1 шт):
Вначале сгенерируем вектор, перпендикулярный данному A
Для этого найдём наибольший и второй по амплитуде компоненты A. Пусть это A.Y и A.Z.
Теперь создадим вектор B = (0, A.Z, -A.Y) - т.е. обнулим наименьший компонент, а два больших обменяем и изменим знак одного из компонентов. Можно заметить, что скалярное произведение A.dot.B равно нулю, т.е. векторы перпендикулярны.
Теперь создадим ещё один вектор C = A x B, используя векторное произведение. Он перпендикулярен как A, так и B.
Нормализуем B и С (разделим на длину)
Выберем случайный угол fi в диапазоне 0..2*Pi и создадим вектор
D = B * cos(fi) + C * sin(fi)
Получился случайный единичный вектор, который лежит в плоскости, нормальной A
Теперь выберем случайный угол theta в в пределах этого самого угла (т.е. до Pi/2 или меньше) и сделаем искомый вектор (да, A нормализован)
E = A * cos(theta) + D * sin(theta)