ПрограммированиеФорумФизика

Снова угловая скорость.

Страницы: 1 2 3 4 5 Следующая »
#0
14:17, 13 июня 2011

Я хочу сделать полёт объекта в воздухе. при этом он может вращаться влево/вправо, вверх/вниз и крутиться. мне нужно что-бы он проделывал все эти действия в зависимости от всех 3 углов то есть если он летит вертикально вниз то при повороте налево или направо он должен изменить своё направление вверх. Пожалуйста дайте формулу для расчёта такой угловой скорости. Вот что у меня уже есть но здесь повороты только по 2 углам и относительно не друг другу а относительно стандартной системы координат:

D3DXVECTOR3 CalcAS(float Ay, float Ax, float S)
{
  float Sp, Ayp, Axp;
  D3DXVECTOR3 Vec;

  Ayp = Ay * 2 * 3.1416f / 360;
  Axp = Ax * 2 * 3.1416f / 360;

  Sp = S * cos(Axp);

  Vec.x = Sp * cos(Ayp);
  Vec.z = Sp * sin(Ayp);
  Vec.y = S * sin(Axp);

  return Vec;
}

Ay, Ax - углы вращения вокруг оси Y и X.
S - скорость объекта.
Ayp, Axp - углы Ax и Ay но в радианах.
Sp - скорость трансформированная под угол Axp.
Возвращается угловая скорость движения в X, Y и Z.

P.S. я только в 6 классе (перехожу в 7) поэтому не надо сложных тригонометрических выражений.

#1
14:45, 13 июня 2011

>В шестом классе? Пойду повешусь, я в таком возрасте только начинал на Delphi формошлепством заниматься...

#2
15:34, 13 июня 2011

speed -> velocity

#3
17:19, 13 июня 2011

Самое простое, что приходит в голову (чтобы не париться про динамику и не узнавать раньше времени про ОДУ) - дема от Марка Харриса/Ансельмо Ластры про облака.  http://www.markmark.net/SkyWorks/

Там хоть и много косинусов, но зато просто мышкой можно поуправлять самолётом.

#4
17:35, 13 июня 2011

kroonk
Не используй углы вообще. Используй направляющие вектора. У самолёта есть три вектора - направление вперёд, вправо и вверх. Если хочешь повернуть направо(относительно самолёта), то вращай направления "вперёд" и "вправо" вокруг направления "вверх". Если хочешь повернуть вверх, вращай направления "вверх" и "вперёд" вокруг направления "вправо".

Если выписать координаты этих углов в три столбика, получится матрица 3х3 - матрица поворота.

#5
18:28, 13 июня 2011

Suslik
А как сделать перемещение и повороты векторами?

#6
19:29, 13 июня 2011

kroonk
> А как сделать перемещение
Перемещение как раз гораздо удобнее, чем углами. Просто прибавляешь к текущей координате самолёта вектор его направления "вперёд", умноженный на величину скорости и на величину шага времени.

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

#7
20:02, 13 июня 2011

Suslik
Я кажется сделал эти векторы а как их в матрицу записать?

#8
20:29, 13 июня 2011

Если тебе хочется получить из них матрицу поворота, то просто запиши их координаты как столбцы матрицы. Но переводить их в матрицу в принципе вообще не обязательно, разве что непосредственно для отрисовки - в остальных случаях с ними можно работать просто как с тройкой векторов.

#9
21:21, 13 июня 2011

Я не правильно поворачиваю векторы. Пожалуйста объясните как правильно как правильно повернуть 2 вектора вокруг третьего?

#10
22:37, 13 июня 2011

У тебя вообще с векторной математикой как? Игровая программерская математика - это не то, чему тебя учат в школе на уроках математике и не совсем то, чему тебя учат на уроках геометрии, это несколько своеобразный раздел, который, вообще говоря, не сложнее и не проще, просто его надо "прочувствовать", через практику.

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

#11
23:11, 13 июня 2011

Suslik
> Ты понимаешь, как реализуются базовые операции с векторами вроде проекции
> вектора на вектор, скалярное/векторное произведение, переход из одной системы
> координат в другую?
Нет. Вы написали что вектор может переходить из одной системы координат в другую я вот что придумал, если нужно повернуть 2 вектора вокруг третьего надо создать систему координат в которой тот вектор вокруг которого вращают был в координатах(0, 1, 0), 1 вращаемый вектор в координатах(0, 0, 1), а 2 в координатах(1, 0, 0). потом повернуть эти 2 вектора вокруг того 3 вектора по какому-нибудь углу и потом все эти векторы перевести обратно в нормальную систему координат, такое возможно? Если да то как это реализовать.

#12
23:55, 13 июня 2011

вот вроде-бы смог реализовать свою идею, это будет работать?:

void PhisicModel::Rotate(char* RVec, float Angle)
{
  float MemV[3][3];
  float A1, A2, A3;
  float Sx1, Sz1;
  float Sx2, Sz2;
  A3 = Angle * 2 * 3.14f / 360;
  if(RVec == "X")
  {
    MemV[0][0] = 0.0f - VecX.x;
    MemV[0][1] = 1.0f - VecX.y; 
    MemV[0][2] = 0.0f - VecX.z;

    VecX.x += MemV[0][0];
    VecX.y += MemV[0][1];
    VecX.z += MemV[0][2];

    MemV[1][0] = -1.0f - VecY.x;
    MemV[1][1] = 0.0f - VecY.y; 
    MemV[1][2] = 0.0f - VecY.z;

    VecY.x += MemV[1][0];
    VecY.y += MemV[1][1];
    VecY.z += MemV[1][2];

    A1 = 270.0f;

    MemV[2][0] = 0.0f - VecZ.x;
    MemV[2][1] = 0.0f - VecZ.y; 
    MemV[2][2] = 1.0f - VecZ.z;

    VecZ.x += MemV[2][0];
    VecZ.y += MemV[2][1];
    VecZ.z += MemV[2][2];

    A2 = (0.0f * 2 * 3.14f / 360);

    Sx1 = 1.0f * cos(A1 + A3);
    Sz1 = 1.0f * sin(A1 + A3);

    Sx2 = 1.0f * cos(A2 + A3);
    Sz2 = 1.0f * sin(A2 + A3);

    VecY.x += Sx1;
    VecY.z += Sz1;

    VecZ.x += Sx2;
    VecZ.z += Sz2;

    VecX.x -= MemV[0][0];
    VecX.y -= MemV[0][1];
    VecX.z -= MemV[0][2];

    VecY.x -= MemV[1][0];
    VecY.y -= MemV[1][1];
    VecY.z -= MemV[1][2];

    VecZ.x -= MemV[2][0];
    VecZ.y -= MemV[2][1];
    VecZ.z -= MemV[2][2];
  }
  if(RVec == "Y")
  {
    MemV[0][0] = 1.0f - VecX.x;
    MemV[0][1] = 0.0f - VecX.y; 
    MemV[0][2] = 0.0f - VecX.z;

    VecX.x += MemV[0][0];
    VecX.y += MemV[0][1];
    VecX.z += MemV[0][2];

    A1 = (90.0f * 2 * 3.14f / 360);

    MemV[1][0] = 0.0f - VecY.x;
    MemV[1][1] = 1.0f - VecY.y; 
    MemV[1][2] = 0.0f - VecY.z;

    VecY.x += MemV[1][0];
    VecY.y += MemV[1][1];
    VecY.z += MemV[1][2];

    MemV[2][0] = 0.0f - VecZ.x;
    MemV[2][1] = 0.0f - VecZ.y; 
    MemV[2][2] = 1.0f - VecZ.z;

    VecZ.x += MemV[2][0];
    VecZ.y += MemV[2][1];
    VecZ.z += MemV[2][2];

    A2 = (0.0f * 2 * 3.14f / 360);

    Sx1 = 1.0f * cos(A1 + A3);
    Sz1 = 1.0f * sin(A1 + A3);

    Sx2 = 1.0f * cos(A2 + A3);
    Sz2 = 1.0f * sin(A2 + A3);

    VecX.x += Sx1;
    VecX.z += Sz1;

    VecZ.x += Sx2;
    VecZ.z += Sz2;

    VecX.x -= MemV[0][0];
    VecX.y -= MemV[0][1];
    VecX.z -= MemV[0][2];

    VecY.x -= MemV[1][0];
    VecY.y -= MemV[1][1];
    VecY.z -= MemV[1][2];

    VecZ.x -= MemV[2][0];
    VecZ.y -= MemV[2][1];
    VecZ.z -= MemV[2][2];
  }
  if(RVec == "Z")
  {
    MemV[0][0] = 1.0f - VecX.x;
    MemV[0][1] = 0.0f - VecX.y; 
    MemV[0][2] = 0.0f - VecX.z;

    VecX.x += MemV[0][0];
    VecX.y += MemV[0][1];
    VecX.z += MemV[0][2];

    A1 = (90.0f * 2 * 3.14f / 360);

    MemV[1][0] = 0.0f - VecY.x;
    MemV[1][1] = 0.0f - VecY.y; 
    MemV[1][2] = -1.0f - VecY.z;

    VecY.x += MemV[1][0];
    VecY.y += MemV[1][1];
    VecY.z += MemV[1][2];

    A2 = (180.0f * 2 * 3.14f / 360);

    MemV[2][0] = 0.0f - VecZ.x;
    MemV[2][1] = 1.0f - VecZ.y; 
    MemV[2][2] = 0.0f - VecZ.z;

    VecZ.x += MemV[2][0];
    VecZ.y += MemV[2][1];
    VecZ.z += MemV[2][2];

    Sx1 = 1.0f * cos(A1 + A3);
    Sz1 = 1.0f * sin(A1 + A3);

    Sx2 = 1.0f * cos(A2 + A3);
    Sz2 = 1.0f * sin(A2 + A3);

    VecX.x += Sx1;
    VecX.z += Sz1;

    VecY.x += Sx2;
    VecY.z += Sz2;

    VecX.x -= MemV[0][0];
    VecX.y -= MemV[0][1];
    VecX.z -= MemV[0][2];

    VecY.x -= MemV[1][0];
    VecY.y -= MemV[1][1];
    VecY.z -= MemV[1][2];

    VecZ.x -= MemV[2][0];
    VecZ.y -= MemV[2][1];
    VecZ.z -= MemV[2][2];
  }
}
MemV - массив сохраняющий отличия положения векторов от новой системы координат.
A1, A2 - уголы в радианах отображающие положения вращаемых векторов.
A3 -  угол в радианах обозначающий на сколько надо повернуть векторы.
Sx1, Sz1 - угловая скорость первого вращаемого вектора.
Sx2, Sz2 - угловая скорость второго вращаемого вектора.
#13
0:07, 14 июня 2011

kroonk
> это будет работать?
нет
строки нельзя сравнивать, сравнивая их их адреса, надо использовать функцию strcmp

#14
1:28, 14 июня 2011

kroonk
> Вы написали что вектор может переходить из одной системы координат в другую я
> вот что придумал, если нужно повернуть 2 вектора вокруг третьего надо создать
> систему координат в которой тот вектор вокруг которого вращают был в
> координатах(0, 1, 0), 1 вращаемый вектор в координатах(0, 0, 1), а 2 в
> координатах(1, 0, 0). потом повернуть эти 2 вектора вокруг того 3 вектора по
> какому-нибудь углу и потом все эти векторы перевести обратно в нормальную
> систему координат, такое возможно? Если да то как это реализовать.
В общем-то как ни странно идея почти правильная. реализация, конечно - сказочная ерунда. Короче несколько советов:

- Не используй градусы вообще нигде, кроме домашнего задания по геометрии. Мысли сразу в радианах, это гораздо удобнее, потому что в них производные синусов/косинусов, перевод из угловых скоростей в линейные и прочие частые операции получаются без нормировочных коэффициентов.

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

- Старайся разбивать свою относительно большую задачу на подзадачи, которые можно решить и отладить отдельно и когда-нибудь потом это решение использовать. В твоём случае элементарная задача - поворот одного вектора вокруг другого, напиши функцию, которая это будет делать. Если ты хочешь повернуть всю модель, то просто вызови функцию поворота для каждого определяющего направления своей модели(суть - для каждого столбца матрицы поворота).

- Не используй то, что не совсем понимаешь, если это не необходимо. Матрицы в твоём случае не необходимы - не используй их.

В общем один из самых простых и эффективных способов повернуть вектор вокруг вектора:
Переходишь в двумерную систему координат, связанную с плоскостью, перпендикулярной оси поворота. В этой плоскости поворачиваешь двумерный вектор - проекция того вектора, который ты изначально хотел повернуть. Ну и потом восстанавливаешь из полученной новой двумерной проекции уже трёхмерный вектор.

Я умышленно не хочу постить готовый код, хочу, чтобы ты сам его вывел.

Страницы: 1 2 3 4 5 Следующая »
ПрограммированиеФорумФизика

Тема в архиве.