Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > Базы данных
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 21.03.2018, 00:11
Аватар для Lothlorien
Lothlorien Lothlorien вне форума
Новичок
 
Регистрация: 06.04.2011
Адрес: Солнечная система
Сообщения: 69
Версия Delphi: 7.0
Репутация: 12
По умолчанию Загадочное вращение вектора

Всем привет! Прошу прощения за нижеследующую простыню текста

Пишу простенькую бродилку-стрелялку с видом сверху, где персонажа можно произвольно вращать вокруг его оси смещением мыши. Умножая вектор его взгляда на матрицу поворота на некий угол, получаю новый вектор, потом картинку персонажа поворачиваю на этот угол и вывожу на экран. Вроде все правильно, но при значениях угла больше 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  
Старый 21.03.2018, 00:13
Аватар для Lothlorien
Lothlorien Lothlorien вне форума
Новичок
 
Регистрация: 06.04.2011
Адрес: Солнечная система
Сообщения: 69
Версия Delphi: 7.0
Репутация: 12
По умолчанию

Черт, еще и не в тот раздел влепил вопрос ((

Проблема решена самостоятельно, прошу прощения за несоответствие тем (как говорится, провтыкал).
__________________
Ne timeas obscurum.

Последний раз редактировалось Lothlorien, 21.03.2018 в 00:43.
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 23:30.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter