Войти
ПрограммированиеФорумГрафика

Инвертирование матрицы

Страницы: 1 2 3 Следующая »
#0
11:23, 16 июня 2009

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

З.Ы. Я не беру в расчёт то, что матрица может быть не правильной и поэтому инвертирование может отличаться, я беру только правильные простые матрицы без извратов...


#1
11:26, 16 июня 2009

у мну так:

FLOAT __forceinline dev3(FLOAT a0,FLOAT a1,FLOAT a2,
           FLOAT a3,FLOAT a4,FLOAT a5,
           FLOAT a6,FLOAT a7,FLOAT a8)
{
  return ( a0*(a4*a8-a7*a5) - a1*(a3*a8-a6*a5) + a2*(a3*a7-a6*a4) );
}

void cMatrix4::toAntimatrix()
{
  FLOAT    dev  =  dev3(elems[0],elems[1],elems[2],
            elems[4],elems[5],elems[6],
            elems[8],elems[9],elems[10]);
  cMatrix4  matr;
  matr.elems[0]  = (elems[5]*elems[10]-elems[6]*elems[9])/dev;
  matr.elems[1]  = -(elems[4]*elems[10]-elems[8]*elems[6])/dev;
  matr.elems[2]  = (elems[4]*elems[9]-elems[8]*elems[5])/dev;
  matr.elems[3]  = -dev3(elems[4],elems[5],elems[6],elems[8],elems[9],elems[10],elems[12],elems[13],elems[14])/dev;

  matr.elems[4]  = -(elems[1]*elems[10]-elems[9]*elems[2])/dev;
  matr.elems[5]  = (elems[0]*elems[10]-elems[8]*elems[2])/dev;
  matr.elems[6]  = -(elems[0]*elems[9]-elems[8]*elems[1])/dev;
  matr.elems[7]  = dev3(elems[0],elems[1],elems[2],elems[8],elems[9],elems[10],elems[12],elems[13],elems[14])/dev;

  matr.elems[8]  = (elems[1]*elems[6]-elems[5]*elems[2])/dev;
  matr.elems[9]  = -(elems[0]*elems[6]-elems[4]*elems[2])/dev;
  matr.elems[10]  = (elems[0]*elems[5]-elems[4]*elems[1])/dev;
  matr.elems[11]  = -dev3(elems[0],elems[1],elems[2],elems[4],elems[5],elems[6],elems[12],elems[13],elems[14])/dev;

  matr.elems[12]  = 0.;
  matr.elems[13]  = 0.;
  matr.elems[14]  = 0.;
  matr.elems[15]  = 1.;

  for(int i=0;i<depth;i++)
    for(int j=0;j<depth;j++)
      elems[4*i+j]  = matr.elems[4*j+i];
}

#2
11:37, 16 июня 2009

Executor
> Разве не существует чёткого описания того как это нужно правильно делать?
Да, есть:  http://en.wikipedia.org/wiki/Inverse_matrix#Methods_of_matrix_inversion

#3
11:39, 16 июня 2009

Как я понимаю из ссылки, способов инвертации несколько и как я понимаю не все они одинакого полезны?

#4
12:02, 16 июня 2009

Обратная матрица, если она существует, единственная. А вот способов ее вычислить много. Иногда даже используют более простые/быстрые методы вычисления для матриц специального вида.

#5
12:17, 16 июня 2009

Кстати, у матрицы поворота (т.к. она ортогональна) инвертированная матрица равна транспонированной. КО

#6
18:26, 16 июня 2009

Executor
> Может ктото объяснить, почему в разных математических библиотеках инвертация
> (ну и детерменант сюда же) делается совершенно по разному?
хотят все побыстрее сделать (в плане скорости выполнения)...

Executor
> Разве не существует чёткого описания того как это нужно правильно делать?
существует. Еще существуют "частные" случаи. В DXUT вроде ф-я инвертирования работает, только если последняя строка матрицы равна "(0, 0, 0, 1)". Зато быстро :) Как сказал KpeHDeJIb, матрицу содержащую только повороты можно просто транспонировать, чтобы получить обратную ей.

#7
18:31, 16 июня 2009

>Разве не существует чёткого описания того как это нужно правильно делать
Мне пожалуйста дайте чёткое описание - что и как во вселенной. Если можно - два экземпляра)))

#8
20:48, 16 июня 2009

http://www.gamedev.ru/community/cfd/articles/RecursiveMethod_

#9
23:05, 16 июня 2009

d.m.k
> KpeHDeJIb, матрицу содержащую только повороты можно просто транспонировать, чтобы получить обратную ей.
На самом деле ничего не надо обращать, достаточно транспонировать!

зы. Можно и внимательней читать посты ;)

#10
23:14, 16 июня 2009

А матрицу просто разложить на две . поворот и перемещение? или это тоже трудоемкая операция? (это я к тому что обе эти матрицы вроде элементарно обращаются - одна транспонированием, другая вообще просто минусы приписать трем числам)

зы
KpeHDeJIb
> d.m.k
> > KpeHDeJIb, матрицу содержащую только повороты можно просто транспонировать,
> > чтобы получить обратную ей.
> На самом деле ничего не надо обращать, достаточно транспонировать!
а что дмк неправильно сказал? он и написл что просто транспонировать нужно.

#11
7:00, 17 июня 2009

Понял... Спасибо всем...

dub
> Обратная матрица, если она существует, единственная. А вот способов ее
> вычислить много. Иногда даже используют более простые/быстрые методы вычисления
> для матриц специального вида.

Пожалуй этот ответ самый чёткий на мой вопрос...

KpeHDeJIb
> Кстати, у матрицы поворота (т.к. она ортогональна) инвертированная матрица
> равна транспонированной. КО

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

Zakus
> Мне пожалуйста дайте чёткое описание - что и как во вселенной. Если можно - два
> экземпляра)))

Я как погляжу ты прям Петросян...

KpeHDeJIb
> На самом деле ничего не надо обращать, достаточно транспонировать!
> зы. Можно и внимательней читать посты ;)

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

Kloun
> А матрицу просто разложить на две . поворот и перемещение?

Поидее такое не должно проканать... Надо попробывать... :)

#12
11:18, 17 июня 2009

Kloun
ну, как вариант - действительно матрицу можно разложить. И взять инвертированные от "простых" матриц. Дело только за "ценой вопроса".

#13
11:28, 17 июня 2009

Если речь идет о матрицах ранга 3 или 4 то там "влоб" пожалуй самый оправданный подход (если только это не
какая-нибудь специальная матрица, типа треугольной или ортогональной, там можно соптимизировать).

#14
13:37, 17 июня 2009

Kloun
А матрицу просто разложить на две: поворот и перемещение? или это тоже трудоемкая операция? (это я к тому что обе эти матрицы вроде элементарно обращаются - одна транспонированием, другая вообще просто минусы приписать трем числам)

Если матрица получена только из композиций (произведений) матриц поворота и перемещения, то ничего раскладывать не надо. Там тоже существует простая формула. Я даже когда-то про это подсказку писал. Код примерно такой:

struct matrix
{
  float
  a11,a12,a13,a14, //x1 x2 x3 dx
  a21,a22,a23,a24, //y1 y2 y3 dy
  a31,a32,a33,a34, //z1 z2 z3 dz
  a41,a42,a43,a44; // 0  0  0  1
  //делает матрицу обратной
  void anti ()
  {
  float
  t1 = -(a11*a41 + a12*a42 + a13*a43),
  t2 = -(a21*a41 + a22*a42 + a23*a43),
  t3 = -(a31*a41 + a32*a42 + a33*a43);

  SWAP(a21,a12);
  SWAP(a31,a13);
  a41 = t1;

  SWAP(a32,a23);
  a42 = t2;

  a43 = t3;

  a14 =
  a24 = 
  a34 = 0;
  a44 = 1;
  }
}

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

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