Вектор (Vector)

From Valve Developer Community
< Ru
Jump to navigation Jump to search
English (en)Deutsch (de)Français (fr)Русский (ru)Translate (Translate)
Info content.png
This page needs to be translated.
This page either contains information that is only partially or incorrectly translated, or there isn't a translation yet.
If this page cannot be translated for some reason, or is left untranslated for an extended period of time after this notice is posted, the page should be requested to be deleted.
Also, please make sure the article complies with the alternate languages guide.(en)

Vector это C++ класс, который представляет направление и длину отрезка прямой, начинающегося в точке отсчёта (origin)(en).

Оси

Каждый вектор содержит три vec_t(en) координаты:

X
+вперёд/-назад
Y
+влево/-вправо
Z
+вверх/-вниз

(1,20,5) означает 1 единица(en) вперёд, 20 единиц влево и 5 единиц вверх.

Note.pngПримечание:Класс вектора в движке Source является геометрическим понятием и сильно отличается от вектора из STL, который является массивом массивом. STL вектор в коде движка был переименован в CUtlVector(en).

Объявление

 Vector vecMyVector = Vector(1,20,5); 
  • Класс вектора пишется как Vector, а не vector.
  • Вы можете определять значения X, Y и Z отдельно.
  • Префикс vec (или просто v) определяет переменную как вектор.

Направление

У вектора нет явно указанного направления, оно определяется кодом, который его использует.

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

Невозможно определить, какая интерпретация будет использоваться для переменной, поэтому изучайте описание используемых функций. Используйте VectorRotate() и VectorIRotate() для преобразования между системами отсчёта.

Использование

Позиционирование
Местоположение каждого объекта 'точка отсчёта (origin)' хранится в виде вектора относительно его родительского(en) объекта в системе декартовых координат(en). Более подробную информацию смотрите в описании функции GetAbsOrigin()(en).
Движение
Объекты перемещаются на расстояние равное вектору скорости(en) один раз в секунду.
Траектории столкновений
Траектория полета(en) рассчитывается из одной точки в другую, определяя, во что она "попадает" на своем пути с учётом ограничивающий габарит (-hull)(en).

Операции

Чтобы результат имел смысл, все векторы в операции должны иметь общую точку отсчёта(en). Используется ли локальное или абсолютное начало отсчёта, зависит от того, чего вы пытаетесь достичь.

Сложение

Сложение двух (или более) векторов складывает их значения. Вы уже складывали векторы, если толкали что либо двумя руками!

Сложение векторов: (4,1) + (-3,1) = (1,2)

Вычитание

Вычитание одного вектора из другого это разница между ними - другими словами, как добраться из первого вектора в другой.

Вычитание векторов: (2,3) - (-2,1) = (4,2)
Tip.pngСовет:От порядка векторов зависит направление получившегося вектора

Умножение(произведение)

Скалярное

Умножение или деление вектора скалярно (то есть на целое(en) или вещественное(en) число) изменит длину вектора не изменяя его направления.

Скалярное произведение векторов: (1,2) x 2 = (2,4)
Tip.pngСовет:Делениние вектора на его длину нормирует(en) его. Используйте VectorNormalize() чтобы быстро это сделать.

Нормированное скалярное

Умножение двух векторов с последующем сложением ординат результата даёт скалярное произведение, которое после нормирования(en) обоих векторов, равно косинусу угла между ними.

Одно из применений скалярного произведения - это определение того, насколько совпадают два вектора. +1 означает совпадение, 0 означает, что они перпендикулярны друг другу, а -1 означает, что они противоположны.

Note.pngПримечание:True dot products are only produced when the length of both vectors is 1. The normal(en)isation step has been skipped in the following demonstration to make its equations simpler (but the positive/zero/negative rule still applies).
Принцип вычисления нормированного скалярное произведения: (2,2) x (-2,0) = (-4,0) = -4; (2,2) x (-2,2) = (-4,4) = 0; (2,2) x (2,2) = (4,4) = 8

Этот код вычисляет скалярное произведение с помощью различных вспомогательных функций Source:

Vector vecTarget = pTarget->GetAbsOrigin() - GetAbsOrigin();	// Get local vector to target
VectorNormalize(vecTarget);	// Normalisation needs to be done beforehand

Vector vecFacing;
AngleVectors(GetLocalAngles(), &vecFacing);	// Convert facing angle to equivalent vector (arrives normalised)

float result = DotProduct(vecTarget, vecFacing);	// Get the dot product

if (result > 0)
	Msg("pTarget is in front of me!\n");
Tip.pngСовет:There is no need to normalise if you only care about whether one location is in front of another.

В этом коде выражение result > 0 истинно, если угол между входными векторами < 90°. Если нужно, чтобы два вектора находились под углом < α градусов друг к другу, то значение result > cos(α°) должно быть истинным, где cos(α°) - константа. Обратите внимание, что таким образом, скалярное произведение позволяет проверить угол между двумя векторами без вызова довольно дорогостоящей функции косинуса во время выполнения.

Icon-Important.pngВажно:Существуют различные объекты, ключ-параметры которых обозначают максимальный угол, который указывается вещественным числом в диапазоне от -1.0 до 1.0, например, ключ-параметр FieldOfView объекта trigger_look. Такие ключ-параметры обычно относятся к скалярному произведению, которое не является линейной функцией желаемого угла. Распространенной ошибкой является установка значения 0.5, которое якобы соответствует углу в 45°, тогда как правильным значением будет cos(45°) ≈ 0.707!
Угол между векторами α° cos-1(значение) 10° 15° 30° 45° 60° 75° 90° 120° 180°
Нормированное скалярное произведение cos(α°) значение 1.0 0.99985 0.99939 0.99619 0.98481 0.96593 0.86603 0.70711 0.5 0.25882 0 -0.5 -1.0

Векторное

Векторное произведение - это вектор, перпендикулярный двум входным векторам. Оно используется для экстраполяции третьего измерения: векторное произведение векторов, направленного вдоль оси X, и вектора, направленного вдоль оси Y, даёт вектор, направленным вдоль оси Z.

Уравнение сложное, но его не нужно заучивать; просто используйте функцию CrossProduct(vecA, vecB, &vecResult). Как правило, нет необходимости нормировать входные векторы. Большинство разработчиков редко будут использовать векторное произведение, если вообще будут, но при необходимости имейте в виду, что для Wikipedia icon small.png правильного понимания этой операции требуется умеренное количество математических вычислений.

Поворот

Для поворота вектора нужна матрица(en), это нельзя сделать также легко как умножение. К счастью не нужно в это вникать: можно просто вызвать VectorRotate(Vector in, QAngle in, Vector& out).

Специальные вектора

В Source есть два вида специальных векторов:

vec3_origin
Vector(0,0,0).
vec3_invalid
Это используется для недопустимых векторов, например, если результатом функцим станет вектор к точке на пересечении двух параллельных прямых.

Функции пользователя

Длина

vec_t(en) Length()
vec_t LengthSqr()
Length() возвращает длину вектора в единицах измерения(en). Быстрее использовать функцию LengthSqr() и возводить в квадрат другое сравниваемое значение.
bool(en) IsLengthGreaterThan(flValue)
bool IsLengthLessThan(flValue)
Функции быстрой проверки длины с использованием LengthSqr().
void Zero()
Устанавливает все ординаты в 0.

Направление

void Init(vec_t X, Y, Z)
Задаёт ординаты существующего вектора.
void Random(vec_t minVal, vec_t maxVal)
Выполняет случайный выбор всех трёх ординат в указанном диапазоне значений.
void Negate()
Меняет ординаты на соотвествующие противоположному направлению вектора, не изменяя его длину.
Vector Max(vOther)
Vector Min(vOther)
Усекает ординаты вектора либо выше, либо ниже заданных значений. Ординаты изменяются независимо, без сохранения пропорций (т.е. направление может измениться).

Сравнение

vec_t DistTo(vOther)
vec_t DistToSqr(vOther)
Возвращает расстояние между текущим и указанным вектором vOther как скалярную величину. Обычно, преобразование в квадрат работает быстрее.
vec_t Dot(vOther)
Возвращает нормированное скалярное произведение текущего и указанного вектора vOther.
Vector Cross(vOther)
Возвращает векторное произведение текущего и указанного вектора vOther.
bool WithinAABox(vecBoxmin,vecBoxmax)
Проверяет, заканчивается ли вектор в пределах заданной прямоугольной области. Минимальные и максимальные точки области расчитываются относительно вектора.

Приведение

Vector2D AsVector2D()
Выполняет приведение вектора к Vector2D(en).
vec_t Length2D()
vec_t Length2DSqr()
As their standard equivalents, but ignoring the Z-axis.
Base()
Casts to vec_t(en)*, basically the same as &vec.x or (float*)&vec.

Вспомогательные функции

Все эти глобальные функции доступны в файле cbase.h.

float(en) VectorNormalize(vec)
Делит вектор на его длину, нормирует(en) его. Умножает вектор и возвращает его изначальную длину.
vec_t(en) DotProduct(vecA, vecB)
Смотрите Нормированное скалярное произведение.
void CrossProduct(vecA,vecB,vecResult)
Смотрите Векторное произведение.
void VectorTransform(Vector in1, matrix3x4_t in2, Vector out)
Смотрите matrix3x4_t(en).

Смотреть также