2

ええ、そうです、クリエイターの目を持たない誰かからの迅速な入力が本当に必要です. 私のテストによると、ここで何かが間違っていscalacheckます...しかし、どこが間違っているのかを知るのに十分な知識はありません。

case class Matrix(_1: (Float, Float, Float, Float), _2: (Float, Float, Float, Float),
                  _3: (Float, Float, Float, Float), _4: (Float, Float, Float, Float)) extends Immutable {
  def invert = {
    val _11 = _2._2 * _3._3 * _4._4 - _2._2 * _3._4 * _4._3 - _3._2 * _2._3 * _4._4
      +_3._2 * _2._4 * _4._3 + _4._2 * _2._3 * _3._4 - _4._2 * _2._4 * _3._3
    val _21 = -_2._1 * _3._3 * _4._4 + _2._1 * _3._4 * _4._3 + _3._1 * _2._3 * _4._4
      -_3._1 * _2._4 * _4._3 - _4._1 * _2._3 * _3._4 + _4._1 * _2._4 * _3._3
    val _31 = _2._1 * _3._2 * _4._4 - _2._1 * _3._4 * _4._2 - _3._1 * _2._2 * _4._4
      +_3._1 * _2._4 * _4._2 + _4._1 * _2._2 * _3._4 - _4._1 * _2._4 * _3._2
    val _41 = -_2._1 * _3._2 * _4._3 + _2._1 * _3._3 * _4._2 + _3._1 * _2._2 * _4._3
      -_3._1 * _2._3 * _4._2 - _4._1 * _2._2 * _3._3 + _4._1 * _2._3 * _3._2
    val _12 = -_1._2 * _3._3 * _4._4 + _1._2 * _3._4 * _4._3 + _3._2 * _1._3 * _4._4
      -_3._2 * _1._4 * _4._3 - _4._2 * _1._3 * _3._4 + _4._2 * _1._4 * _3._3
    val _22 = _1._1 * _3._3 * _4._4 - _1._1 * _3._4 * _4._3 - _3._1 * _1._3 * _4._4
      +_3._1 * _1._4 * _4._3 + _4._1 * _1._3 * _3._4 - _4._1 * _1._4 * _3._3
    val _32 = -_1._1 * _3._2 * _4._4 + _1._1 * _3._4 * _4._2 + _3._1 * _1._2 * _4._4
      -_3._1 * _1._4 * _4._2 - _4._1 * _1._2 * _3._4 + _4._1 * _1._4 * _3._2
    val _42 = _1._1 * _3._2 * _4._3 - _1._1 * _3._3 * _4._2 - _3._1 * _1._2 * _4._3
      +_3._1 * _1._3 * _4._2 + _4._1 * _1._2 * _3._3 - _4._1 * _1._3 * _3._2
    val _13 = _1._2 * _2._3 * _4._4 - _1._2 * _2._4 * _4._3 - _2._2 * _1._3 * _4._4
      +_2._2 * _1._4 * _4._3 + _4._2 * _1._3 * _2._4 - _4._2 * _1._4 * _2._3
    val _23 = -_1._1 * _2._3 * _4._4 + _1._1 * _2._4 * _4._3 + _2._1 * _1._3 * _4._4
      -_2._1 * _1._4 * _4._3 - _4._1 * _1._3 * _2._4 + _4._1 * _1._4 * _2._3
    val _33 = _1._1 * _2._2 * _4._4 - _1._1 * _2._4 * _4._2 - _2._1 * _1._2 * _4._4
      +_2._1 * _1._4 * _4._2 + _4._1 * _1._2 * _2._4 - _4._1 * _1._4 * _2._2
    val _43 = -_1._1 * _2._2 * _4._3 + _1._1 * _2._3 * _4._2 + _2._1 * _1._2 * _4._3
      -_2._1 * _1._3 * _4._2 - _4._1 * _1._2 * _2._3 + _4._1 * _1._3 * _2._2
    val _14 = -_1._2 * _2._3 * _3._4 + _1._2 * _2._4 * _3._3 + _2._2 * _1._3 * _3._4
      -_2._2 * _1._4 * _3._3 - _3._2 * _1._3 * _2._4 + _3._2 * _1._4 * _2._3
    val _24 = _1._1 * _2._3 * _3._4 - _1._1 * _2._4 * _3._3 - _2._1 * _1._3 * _3._4
      +_2._1 * _1._4 * _3._3 + _3._1 * _1._3 * _2._4 - _3._1 * _1._4 * _2._3
    val _34 = -_1._1 * _2._2 * _3._4 + _1._1 * _2._4 * _3._2 + _2._1 * _1._2 * _3._4
      -_2._1 * _1._4 * _3._2 - _3._1 * _1._2 * _2._4 + _3._1 * _1._4 * _2._2
    val _44 = _1._1 * _2._2 * _3._3 - _1._1 * _2._3 * _3._2 - _2._1 * _1._2 * _3._3
      +_2._1 * _1._3 * _3._2 + _3._1 * _1._2 * _2._3 - _3._1 * _1._3 * _2._2

    val det = _1._1 * _11 + _1._2 * _21 + _1._3 * _31 + _1._4 * _41
    if (det == 0) this
    else Matrix(
      (_11, _12, _13, _14),
      (_21, _22, _23, _24),
      (_31, _32, _33, _34),
      (_41, _42, _43, _44)
    ) * (1 / det)
  }

  def *(f: Float) = Matrix(
    (_1._1 * f, _1._2 * f, _1._3 * f, _1._4 * f),
    (_2._1 * f, _2._2 * f, _2._3 * f, _2._4 * f),
    (_3._1 * f, _3._2 * f, _3._3 * f, _3._4 * f),
    (_4._1 * f, _4._2 * f, _4._3 * f, _4._4 * f)
  )
}

また、このマトリックスを OpenGL にロードできますか、それとも最初に転置する必要がありますか。私は本当にこの数学についていつも混乱します。

4

4 に答える 4

3

計算が悪条件になる可能性があるため、行列を反転することは通常はお勧めできません。

連立方程式を解きたい場合は、特に分解を再利用していくつかの右辺ベクトルを解くことができる場合は、LU 分解や前方後方置換などを使用して解くことをお勧めします。

このリンクは、ピボットを使用したガウス消去の Java の例を示しています。

別の考えとして、JAMA の後継であるApache Commons Mathのような Java ライブラリをアプリケーションで使用できるのではないでしょうか?

特定のケースを念頭に置いている場合は、それをWolfram Alphaに入力して、コーディングを開始する前に答えがどうあるべきかを確認することをお勧めします.

于 2011-05-21T18:20:39.043 に答える
2

数値で遊んでみたい場合は、ぜひ自分でやってみてください。Jesper と duffymo から良い提案があります (逆行列は実際には役に立ちません。LU 分解を調べてください)。

ただし、 Get Stuff Done TMだけを使用したい場合は、ScalalaScalalabを調べてください。

いずれにせよ、線形代数の背景知識が必要になります。これは、多くの分野で非常に役立つ数学です。

于 2011-05-21T20:43:34.233 に答える
2

私はSimplex3Dがこの計算を実装していると確信しています (そして、そこで正しく行われている可能性が非常に高いです)。

于 2011-05-21T18:26:25.730 に答える
1

ウィキペディアの Invertible matrix: Analytic solutionを参照してください。上部の一連の計算は、行列式の計算元である行列の随伴行列を計算し、逆1 / det行列は随伴行列を掛けたものです。

ここに画像の説明を入力

計算全体は、コード内の 4 x 4 マトリックスに対して明示的に記述されているため、バグがある場合は、全体をチェックするのにいくらかの労力が必要になります。ウィキペディアの記事では、それがどのように機能するかを説明しています。

于 2011-05-21T17:42:00.367 に答える