Зачем нужны векторы и как ими пользоваться? Краткий обзор python модуля vector3d

Все, кто хоть раз писал на BGT, должны помнить про векторы.
Почему-то так повелось, что их стали использовать как контейнеры для координат игрока, а про то, что векторы — вообще-то отрезки с направлением, все забыли.
Так вот, небольшой экскурс в геометрию и физику.
В геометрии вектор — это отрезок имеющий направление. то есть имеющий начало и конец. Вектор AB это не то же самое, что вектор BA, так как в математике векторы всегда обозначаются от начала к концу.
В физике векторами задаются многие величины, например, скорость, сила (она же тоже имеет направление), ускорение, перемещение и т д.
В играх, в особенности в космических симуляторах, где мы не можем сделать один шаг вперёд, а должны лететь непрерывно, векторы как никогда уместны.
Есть вектор скорости, который одновременно задаёт саму скорость корабля (длина вектора) и направление полёта (направление вектора). Есть ускорение, которое может совпадать со скоростью, а может двигать корабль под углом к скорости (в таком случае векторы складываются)… Вариантов применения много, а главное, они позволяют добиться точности расчётов и избежать костылей в виде перемещения по таймеру (if t.elapsed >= speed) {ship.move(); })

Теперь немного о vector3d

В модуле на данный момент реализовано два подмодуля: vector для работы с векторами и point для работы с точками. Кстати в Point как раз можно и нужно хранить координаты игрока (ибо точка это и есть точка).

В подмодуле vector3d.vector содержится класс Vector, который и представляет собой реализацию вектора.
Vector(x=0, y=0, z=0)
То есть вы можете задать вектор как Vector(1, 2, 3), так и Vector(2, 5) и даже Vector(4), недостающие координаты будут заполнены нулевыми значениями.

С векторами можно совершать почти все арифметические действия:
сложение a + b — возвращает вектор
вычитание a — b — возвращает вектор, но зачем вычитать если можно складывать?
Скалярное произведение — зачем оно в играх, непонятно, но на всякий случай добавил. Возвращает число, так как скалярное ведь.

Также можно делать так:
a += b
a -= b
а вот с умножением в таком виде я решил не рисковать, ибо нарушает пару математических законов в их python реализации.
и ещё, конечно же, метод a.length(), возвращает длину вектора (число типа float)

Помимо Vector() подмодуль vector3d.vector содержит в себе несколько функций, не являющихся методами какого-либо класса (их можно импортировать отдельно, без всего модуля):
angle(a, b) угол между двумя векторами (в таком виде в играх не имеет смысла)
horizontal_angle(a, b) угол между проекциями векторов на плоскость Oxy (горизонтальный угол, без учёта Z координаты)
vertical_angle(a, b) угол между проекциями векторов на плоскость Oyz (вертикальный угол, без учёта X координаты. проще говоря, направление взгляда относительно «вверх» и «вниз»)
from_points(a, b) построить вектор с началом в a и концом в b, в чистом виде в играх почти не используется, но решил всё же реализовать на всякий случай.

Второй подмодуль, point, отвечает за реализацию точек в 3D пространстве.
point.Point и есть класс точки.
её можно создать как и вектор:
Point(x, y, z)
Point(x, y)
Point(x)
Работает как с векторами, никаких изменений.
Методов, кстати, у точки пока нет, ибо без надобности, а вот дополнительные функции имеются.

distance(a, b) возвращает расстояние между двумя точками (реализация проверена математиком, так что ошибок Сэма не будет)
center(a, b) возвращает координаты середины между двумя точками, то есть середины отрезка AB.

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

Автор публикации

не в сети 4 года

best_gamer

Комментарии: 0Публикации: 10Регистрация: 12-07-2015

Добавить комментарий