atan2f() не работает

Я пытаюсь изменить ориентацию своих объектов по направлению к центру с помощью atan2f, но это дает мне неправильное значение. Я где-то ошибся?

glm::vec3 center = glm::vec3(0.4f, 0.4f, 0.0f);
for(int i = 0; i < num; i++){
  float rel = i / (float) num;
  float angle = rel * M_PI * 2;
  glm::vec3 position = glm::vec3(cos(angle), glm::sin(angle), position.z);

  position.x *= radius; position.y *= radius;
  position.x += center; position.y += center;
  glm::mat4 trans = glm::translate(glm::mat4(1.0f), position);

  float newAngle = atan2f(position.y - center.y, position.x - center.x);

  glm::mat4 rotation = glm::rotation(glm::mat4(1.0f), newAngle, glm::vec3(0, 0, 1));

  numModel.at(i) = trans * rotation;
}

person Vitge    schedule 21.07.2017    source источник
comment
Можете ли вы заметить что-то особенное в неправильном значении? Возможно, вам нужно инвертировать знак или добавить к нему pi/2 или что-то подобное.   -  person HolyBlackCat    schedule 21.07.2017
comment
@HolyBlackCat Спасибо за ваш ответ. У меня есть 3 объекта, если я попытаюсь изменить их угол с помощью atan2f, у меня один останется на 0 градусов, другой примерно на 120 градусов и еще один -120 градусов. Значение прав должно быть 90 градусов, 135 градусов примерно, а последнее тоже примерно -135 градусов.   -  person Vitge    schedule 21.07.2017


Ответы (1)


Если вы хотите повернуть объект вокруг центра мира, вам нужно сначала настроить матрицу вращения:

float angle = ...;
glm::vec3 rotAxis( ... );
glm::mat4 rotMat = glm::rotation( glm::mat4(1.0f), angle, rotAxis );

Обратите внимание, что функция glm::rotation вычисляет синус и косинус угла и устанавливает соответствующие поля внутри матрицы.

2-й вам нужно настроить матрицу положения объектов, это матрица, которая описывает начальное положение объекта:

glm::vec3 position( radius, 0.0f, 0.0f );
glm::mat4 transMat = glm::translate( glm::mat4(1.0f), position );

Чтобы повернуть объект вокруг центра мира, вы должны умножить матрицу вращения rotMat на матрицу модели transMat, потому что матрица вращения определяет систему отсчета для размещения объекта.

glm::mat4 modelMat = rotMat * transMat;

Если вы хотите повернуть объект вокруг его собственного начала, вы должны сначала поместить свой объект в мир, а затем повернуть его:

glm::mat4 modelMat = transMat * rotMat;

См. также ответ на вопрос преобразование объектов OpenGL с несколькими поворотами разных осей

В вашем случае, когда вы хотите, чтобы объект был направлен в центр мира, вам сначала нужно перевести объект на его место. Во-вторых, вы должны рассчитать угол между осью X мира и направлением от объекта к центру. Наконец, вы должны повернуть объект в противоположном направлении.

 glm::vec3 position( ... );
 glm::vec3 center( ... );
 glm::mat4 transMat = glm::translate( glm::mat4(1.0f), position );

 float angle = atan2f(center.y - position.y, center.x - position.x);

 glm::vec3 rotAxis( 0.0f, 0.0f, 1.0f );
 glm::mat4 rotMat = glm::rotation( glm::mat4(1.0f), -angle, rotAxis );

 glm::mat4 modelMat = transMat * rotMat;
person Rabbid76    schedule 21.07.2017
comment
Привет, я уже создал объект вокруг центра и сделал перевод. Что я пытаюсь сделать, так это не вращать вокруг центра, а ориентировать вершины моих объектов в центр. - person Vitge; 21.07.2017
comment
Спасибо, было это... Так очевидно - person Vitge; 23.07.2017