|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
|
Опции темы | Поиск в этой теме | Опции просмотра |
|
#1
|
||||
|
||||
Загадочное вращение вектора
Всем привет! Прошу прощения за нижеследующую простыню текста
Пишу простенькую бродилку-стрелялку с видом сверху, где персонажа можно произвольно вращать вокруг его оси смещением мыши. Умножая вектор его взгляда на матрицу поворота на некий угол, получаю новый вектор, потом картинку персонажа поворачиваю на этот угол и вывожу на экран. Вроде все правильно, но при значениях угла больше 180° и меньше 0° начинаются глюки: персонаж физически "смотрит" в правильном направлении, но визуально (графически) - совсем в другую сторону. Если дискретно вращать его в одну сторону, то при достижении нуля или 180 градусов он визуально начинает вращаться в противоположном направлении (но фактически это не так), и при попытке управлять персонажем он словно "идет боком". Покопался в коде, и единственное место, где может быть спрятана проблема, находится в функции, которая определяет угол между двумя векторами: Код:
function TMain.Angle(const V1, V2: TVector): Single; var S: Single; W1, W2: TVector; function SD(const N, D: Single): Single; // предотвращение деления на ноль begin if D <> 0 then Result:=N / D else Result:=0; end; function Norm(const V: TVector): TVector; // нормализация вектора var L: Single; begin L:=sqrt(V.X * V.X + V.Y * V.Y); Result.X:=SD(V.X, L); Result.Y:=SD(V.Y, L); end; begin W1:=Norm(V1); W2:=Norm(V2); S:=W1.X * W2.X + W1.Y * W2.Y; // скалярное произведение Result:=ArcTan2(sqrt(1 - S * S), S) * 180 / PI {арккосинус скалярного произведения (из Math.pas), возвращаем значение в градусах} end; Код:
TVector = record X, Y: Single; end; {...} function Vector(X, Y: Single): TVector; // "конструктор" вектора begin Result.X:=X; Result.Y:=Y; end; Считаем угол взгляда так: Код:
A:=Angle(Look, Vector(1.0, 0.0)); {Angle - вектор взгляда персонажа; нолевое вращение соответствует взгляду на восток.} Полученный угол применяется как аргумент функции вращения изображения (этой), и на выходе имеем вращение только на "верхней половине окружности". Виноват во всем ArcTan2, который возвращает значения от -Pi до +Pi, то есть именно мои (-180 .. 180)°. Что делать? Я пробовал возвращать и отрицательный результат, когда скалярное произведение меньше нуля (векторы "смотрят" в разные стороны), и значение (360 - Result), и (90 + Result) - все равно получается черти-что. Как можно решить эту проблему? Ne timeas obscurum. |
#2
|
||||
|
||||
Черт, еще и не в тот раздел влепил вопрос ((
Проблема решена самостоятельно, прошу прощения за несоответствие тем (как говорится, провтыкал). Ne timeas obscurum. Последний раз редактировалось Lothlorien, 21.03.2018 в 00:43. |