Войти
ПрограммированиеСтатьиОбщее

ЧАВО по матрицам и кватернионам (6 стр)

Автор:

Как мне преобразовать угол вращения ось в кватернион?

  Даны ось и угол вращения, следующий алгоритм используется для
  создания кватерниона:

    sin_a = sin( angle / 2 )
    cos_a = cos( angle / 2 )

    q -> x    = axis -> x * sin_a
    q -> y    = axis -> y * sin_a
    q -> z    = axis -> z * sin_a
    q -> w    = cos_a

    quaternion_normalise( q );
 

  Не надо нормализовать кватернион, если величины очень малы.

Как мне преобразовать кватернион в ось и угол?


----------------------------------------------------------------

  Кватернион может быть преобразован обратно в ось и угол
  следующим алгоритмом:

    quaternion_normalise( qr );

    cos_angle  = qr -> qw;
    angle      = acos( cos_angle ) * 2 * RADIANS;
    sin_angle  = sqrt( 1.0 - cos_angle * cos_angle );

    if ( fabs( sin_angle ) < 0.0005 )
      sa = 1;

    axis -> vx = qr -> qx / sa;
    axis -> vy = qr -> qy / sa;
    axis -> vz = qr -> qz / sa;

Как мне преобразовать сферические углы вращения в кватернион?

  Оси вращения сами по себе могут быть заданы в сферических координатах и угле вращения.

  Поэтому, кватернион можно считать так:
 

    sin_a   = sin( angle / 2 )
    cos_a   = cos( angle / 2 )

    sin_lat  = sin( latitude )
    cos_lat  = cos( latitude )

    sin_long = sin( longitude )
    cos_long = cos( longitude )

    qx       = sin_a * cos_lat * sin_long
    qy       = sin_a * sin_lat
    qz       = sin_a * sin_lat * cos_long
    qw       = cos_a

Как перевести кватернион в сферические углы вращения?



  Кватернион преобразуется в сферические координаты так:
 
    cos_angle = q -> qw;
    sin_angle = sqrt( 1.0 - cos_angle * cos_angle );
    angle     = acos( cos_angle ) * 2 * RADIANS;

    if ( fabs( sin_angle ) < 0.0005 )
      sa = 1;

    tx = q -> qx / sa;
    ty = q -> qy / sa;
    tz = q -> qz / sa;

    latitude = -asin( ty );

    if ( tx * tx + tz * tz < 0.0005 )
      longitude  = 0;
    else
       longitude = atan2( tx, tz ) * RADIANS;

    if( longitude < 0 )
      longitude+= 360.0;

Как преобразовать углы Эйлера в кватернион?

  Преобразование углов Эйлера в кватернион достигается через умножение
  кватернионов. Каждый угол вращения преобразуется в пару ось-угол,

  с осью отвечающей Эвклидовой оси. Пары ось-угол преобразуются в кватернион
  и перемножаются. В результате будет нужный кватернион.

  Код демонстрирующий это:

  quaternion_from_euler( QUATERNION *q, VFLOAT ax, VFLOAT ay, VFLOAT az ){
    VECTOR3 vx = { 1, 0, 0 }, vy = { 0, 1, 0 }, vz = { 0, 0, 1 };
    QUATERNION qx, qy, qz, qt;

    quaternion_from_axisangle( qx, &vx, rx );
  quaternion_from_axisangle( qy, &vy, ry );
  quaternion_from_axisangle( qz, &vz, rz );
    quaternion_multiply( &qt, &qx, &qy );
    quaternion_multiply( &q,  &qt, &qz );
  }

Как мне с помощью кватернионов линейно интерполировать между матрицами?

  Для многих анимационных программ, необходимо интерполировать между
  двумя вращениями объекта. Эти позиции могутбыть заданы ключевыми
  кадрами анимации, или инверсной кинематикой.
  Используя этот метод, необходимо знать обе матрицы и задачей является
  интерполяция между ними. Две матрицы представляют собой
  начальную и конечную матрицы ( MS и MF).

  При использовании линейной интерполяции, интерполированные
  матрицы вращения создаются при помощи уравнения смешивания
  с параметром T, который меняется от 0.0 до 1.0.
 
  При Т=0, интерполированная матрица равна начальной.
  При Т=1, интерполированная матрица равна конечной.
 
  Интерполяция описывается так:

    MI = F( MS, MI, T )
  где F функция смешивания.

  На первом этапе определяют матрицу, которая преобразует MS в MF:

           -1
     T = Ms  . Mf
  где Ms - начальная матрица,
      Mf - конечная матрица,
    и T  - матрица преобразования.

  Потом эту матрицу преобразуют в угол ось и угол поворота.
  Что делается через преобразование матрицы в кватернион,
  а затем в ось и угол вращения.
 
  Чтобы создать интерполированную матрицу, необходимо только скалировать
  угол поворота и преобразовать этот угол и ось обратно в матрицу поворота.
 
  Для матриц 4х4 код будет выглядеть так:

    m4_transpose(    mt, ms );                /* Обращение            */
    m4_mult(         ms, mt, mb );            /* Матрица вращения     */
    m4_to_axisangle( ms, axis, angle );       /* ось и угол вращения  */

    for( t = 0; t < 1.0; t += 0.05 ){
      m4_from_axisangle( mi, axis, angle * t ); /* Интерполяция */

      ... делаем что-то ...

      }
  где t фактор интерполяции от 0.0 до 1.0

Как мне с помощью кватернионов сделать кубическую интерполяцию между матрицами?

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

  Их умножают с начальной матрицей для Кардиального сплайна.
  Это интерполированная матрица затем используется для определения
  сферических углов вращения.

  Как только интерполированные координаты известны, интерполированная
  матрица вращения может быть создана через перевод в кватернион.
 
  Для матриц 4х4, алгоритм будет таким:
 

    for ( n = 0; n < 4; n++ )
      m4_to_spherical( mat[n], &v_sph[n] );      /* Сферические координаты */
      m4_multspline( m_cardinal, v_sph, v_interp ); /* Вектор интерполяции */

    ...

    v3_cubic( v_pos, v_interp, t );            /* Интерполяция */
    m4_from_spherical( m_rot, v_pos );        /* Возврат к матрице */

Это ЧАВО составлено этим человеком и переведено на русский мной.
Любые предложения и дополнения приветствуются. Шлите их на мыло этому чуваку.

Самая свежая версия статьи может быть найдена тут:
  ftp://ftp.netcom.com/pub/he/hexapod/index.html
  http://www.glue.umd.edu/~rsrodger

Пожертвования


 
Страницы: 1 2 3 4 5 6

#C++, #OpenGL, #кватернионы, #математика, #матрицы

9 марта 2011 (Обновление: 25 мая 2020)

Комментарии [40]