Добро пожаловать на Pro Pawn - Портал о PAWN-скриптинге.
Показано с 1 по 1 из 1

Тема: Углы и оси

  1. #1
    Аватар для Osetin
    •Администратор•

    Статус
    Оффлайн
    Регистрация
    26.03.2013
    Адрес
    ♔Osetia, Vladikavkaz♔
    Сообщений
    3,432
    Репутация:
    1093 ±

    Углы и оси

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

    Дело в том, что стандартная ось и ось GTA SA хоть и схожы, но имеют различие. 0 градусов не 0, и 180 тоже не 180. Почему же?



    Как видно, углы смещены путём поворота осей на 90 градусов против часовой стрелки.



    Из этого следует, что уже X не связан с cos, а Y не связан с sin. X уже будет связан с sin, а Y будет уже связан с cos.

    Как пример, попробуем понять, почему именно так.
    Создадим два рисунка с осями без названий. Один рисунок - для Y, второй - для X.



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



    А теперь повернем эти рисунки на 90 градусов по часовой стрелке.



    Как мы видим, Y связан с cos, а X связан с -sin. В итоге, получаем, что если мы хотим создать какой-либо элемент впереди игрока, то:
    PHP код:
    new Float:p[4];
    new 
    Float:dist 5.0//дистанция, на котором будет создан объект
    GetPlayerPos(playerid,p[0],p[1],p[2]);
    GetPlayerFacingAngle(playerid,p[3]);
    CreateObject(modelid,p[0]+dist*-floatsin(p[3],degrees),p[1]+dist*floatcos(p[3],degrees),p[2],0.0,0.0,0.0,300.0); 
    Хотите создать элемент где-то сбоку игрока, или даже сзади? Просто добавьте к текущей ротации игрока требуемый угол.
    PHP код:
    new Float:p[4];
    new 
    Float:dist 5.0//дистанция, на которой будет создан объект
    GetPlayerPos(playerid,p[0],p[1],p[2]);
    GetPlayerFacingAngle(playerid,p[3]);
    p[3] = p[3] + 45.0//прибавление угла; можно и отнимать
    CreateObject(modelid,p[0]+dist*-floatsin(p[3],degrees),p[1]+dist*floatcos(p[3],degrees),p[2],0.0,0.0,0.0,300.0); 
    Задается вопрос: А зачем все эти синусы и косинусы? Нет другого способа? Ответ: нет, нету. Синус и косинус позволяют нам делать создание элемента именно с наиточнейшим расстоянием от игрока.



    Все эти отрезки (L1,...,L8) равны между собой, т.к. являются радиусами. Таким образом, синус и косинус помогают вычислить нам расстояния, которые нужно изменить по X и Y, чтобы получить такой радиус.

    А теперь перейдем к трехмерному пространству, особенно к функции GetPlayerCameraFrontVector.
    Как ни странно, эта функция ведет себя, как в стандартном пространстве и с учетом игрового одновременно. Но она уже возвращает данные, преобразованные косинусом и синусом, то есть уже использовать угол поворота игрока, в принципе, не совсем нужно. Ан нет, он всё равно потребуется в каком-нибудь случае, так как обновление данных о камере идет куда не так часто, как обновление ротации игрока по Z.



    Таким образом, красная зона отвечает за значения по Y и X, а синяя зона - за значение по Z.



    А каков же угол по Z у камеры? Z связан с sin, поэтому достаточно легко понять, что для узнавания угла наклона нужно использовать asin:

    PHP код:
    new Float:p[3],Float:ang;
    GetPlayerCameraFrontVector(playerid,p[0],p[1],p[2]);
    ang asin(p[2]); 
    Изменение угла - от -90 до 90.

    Как пример, сделаем так, чтобы создавался объект именно там, куда смотрит игрок.

    PHP код:
    new Float:p[3],Float:pp[3];
    new 
    Float:dist 5.0;
    GetPlayerCameraFrontVector(playerid,p[0],p[1],p[2]);
    GetPlayerCameraPos(playerid,pp[0],pp[1],pp[2]);
    CreateObject(3798,pp[0]+dist*p[0],pp[1]+dist*p[1],pp[2]+dist*p[2],0,0,0); 
    Напомню, что здесь мы не используем sin и cos, так как GetPlayerCameraFrontVector уже высчитала нам различие.
    Использовать позицию игрока будет неверным способом, так как камера смотрит не точно на позицию игрока.



    Автор темы и рисунков: Quantra

  2. 9 пользователя(ей) сказали cпасибо:
    BodyanZe (07.08.2017) Daniel_Cortez (15.08.2013) Edwin (21.03.2016) GeeRoN_ZeRO (01.07.2014) L0ndl3m (24.12.2013) Nexius_Tailer (24.04.2016) Nixon (08.04.2014) R.GAGIEV (08.09.2013) Smile (08.09.2013)
 

 

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Ваши права

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