Vala プログラミング

WebGPU プログラミング

おなが@京都先端科学大

Vala OepnGL ( ValaGL MatrixMath.vala )

ValaGL MatrixMath.vala の演算
Mat3(3x3 行列)

Mat3 の定義
struct Mat3
  メンバー
  float data[9]
      Mat3 の各要素
      m11(data[0]), m12(data[3]), m13(data[6])
      m21(data[1]), m22(data[4]), m23(data[7])
      m31(data[2]), m32(data[5]), m33(data[8])

  メソッド
  *生成
  Mat3()
      要素が 0 値の Mat3 を生成
      (Creates a new matrix, zero initialized.)
  Mat3.from_data (GLfloat a11, GLfloat a12, GLfloat a13,
    GLfloat a21, GLfloat a22, GLfloat a23,
    GLfloat a31, GLfloat a32, GLfloat a33)
      要素が、以下のようになる Mat3 を生成
      m11 = a11, m12 = a12, m13 = a13
      m21 = a21, m22 = a22, m23 = a23
      m31 = a31, m32 = a32, m33 = a33
      (Creates a matrix whose contents are the copy of the given data.
       Warning: the data are specified in column-first-index order,
       which is different from the internal storage format
       (row-first-index).)

  Mat3.from_vec_mul (ref Vec3 a, ref Vec3 b)
      2つの Vec3 a, b から Mat3 を生成(a * bT の計算、bT は b の
      転置ベクトル)
      m11 = a.x * b.x, m12 = a.x * b.y, m13 = a.x * b.z
      m21 = a.y * b.x, m22 = a.y * b.y, m23 = a.y * b.z
      m31 = a.z * b.x, m32 = a.z * b.y, m33 = a.z * b.z
      (Given two vectors a and b, computes a matrix equal to a * bT.)
  Mat3.from_array (GLfloat data)
      要素が配列 data で与えられる Mat3 を生成
      m11 = data[0], m12 = data[3], m13 = data[6]
      m21 = data[1], m22 = data[4], m23 = data[7]
      m31 = data[2], m32 = data[5], m33 = data[8]
      (Creates a matrix whose contents are the copy of the given
       array,assumed to have at least 9 elements.)
  Mat3.identity ()
      単位行列を生成
      m11 = 1, m12 = 0, m13 = 0
      m21 = 0, m22 = 1, m23 = 0
      m31 = 0, m32 = 0, m33 = 1
      (Creates an identity matrix.)

  *ベクトル演算
  void add (ref Mat3 other)
      this(インスタンス)と other 行列との和(要素間の和)
      (Adds the given matrix, component-wise.)
  void sub (ref Mat3 other)
      this(インスタンス)と other 行列との差(要素間の差)
      this から other 行列を引く
      (Subtracts the given matrix, component-wise.)

  void mul (GLfloat factor)
      this(インスタンス)の各要素をfactor倍する
      (Multiplies the matrix by the given scalar, component-wise.)
  void div (GLfloat factor)
      this(インスタンス)の各要素をfactorで割る
      (Divides the matrix by the given scalar, component-wise.)

      void mul_mat (ref Mat3 other)
      this(インスタンス、Mat3)と other 行列(Mat3)の積
     ( this × other )
      m11 = m11*other11 + m12*other21 + m13*other31
      m12 = m11*other12 + m12*other22 + m13*other32
      m13 = m11*other13 + m12*other23 + m13*other33
      m21 = m21*other11 + m22*other21 + m23*other31
      m22 = m21*other12 + m22*other22 + m23*other32
      m23 = m21*other13 + m22*other23 + m23*other33
      m31 = m31*other11 + m32*other21 + m33*other31
      m32 = m31*other12 + m32*other22 + m33*other32
      m33 = m31*other13 + m32*other23 + m33*other33
      (Multiplies the given matrix using the linear algebra definition
       of matrix multiplication.)
  Vec3 mul_vec (ref Vec3 vec)
      this(インスタンス, Mat3)と vec ベクトル(Vec3) の積
      ( this × vec )
      生成されるベクトル(Vec3): v
      v.x = m11*vec.x + m12*vec.y + m13*vec.z
      v.y = m21*vec.x + m22*vec.y + m23*vec.z
      v.z = m31*vec.x + m32*vec.y + m33*vec.z
      (Multiplies this matrix by the given vector and returns the result
       as a new vector.)
  Mat3 transposed ()
      this(インスタンス, Mat3)の転置行列を生成
      生成される転置行列(Mat3): A
      a11 = m11, a12 = m21, a13 = m31
      a21 = m12, a22 = m22, a23 = m32
      a31 = m13, a32 = m23, a33 = m33
      Returns a new matrix that is the transposition of this matrix.
  GLfloat det ()
      this(インスタンス, Mat3)の行列式を計算
      行列式の値: D
      D = m11*(m22*m31 - m32*m23) - m12*(m21*m33 - m31*m23)
         + m13*(m21*m32 - m31*m22)
      Computes the determinant of this matrix.
  Mat3 inverted (out bool success)
      this(インスタンス, Mat3)の逆行列を生成
      this(インスタンス)の行列式の値: D
      生成される逆行列(Mat3): A
      逆行列が存在しない場合(D = 0)、success に "false" が設定
         される。
      逆行列が存在する場合(D ≠ 0)、success に "true" が設定され、
         逆行列が生成される。
      a11 = (m22*m33 - m32*m23) / D
      a12 = -(m12*m33 - m32*m13) / D
      a13 = (m12*m23 - m22*m13) / D
      a21 = -(m21*m33 - m31*m23) / D
      a22 = (m11*m33 - m31*m13) / D
      a23 = -(m11*m23 - m21*m13) / D
      a31 = (m21*m32 - m31*m22) / D
      a32 = -(m11*m32 - m31*m12) / D
      a33 = (m11*m22 - m21*m12) / D
      Returns a new matrix that is the inversion of this matrix.
      @param success Set to ``false`` if the matrix cannot be inverted
       (its determinant is zero) and ``true`` otherwise.
      @return The inverted matrix if the matrix was successfully
       inverted, otherwise the return value is undefined.


1 ベクトルの生成
## prog1
## main.vala
// Mat3 生成
using ValaGL.Core;

void main () {
    var a = Mat3 ();
    // a11(data[0])= 0, a12(data[3])= 0, a13(data[6])= 0
    // a21(data[1])= 0, a22(data[4])= 0, a23(data[7])= 0
    // a31(data[2])= 0, a32(data[5])= 0, a33(data[8])= 0
    stdout.printf ("Mat3 A\n");
    stdout.printf ("a11=%f a12=%f a13=%f \n", a.data[0], a.data[3],
       a.data[6]);
    stdout.printf ("a21=%f a22=%f a23=%f \n", a.data[1], a.data[4],
       a.data[7]);
    stdout.printf ("a31=%f a32=%f a33=%f \n", a.data[2], a.data[5],
       a.data[8]);
    stdout.printf ("\n");

    a = Mat3.from_data (1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f,
       7.0f, 8.0f, 9.0f);
    // a11(data[0])= 1, a12(data[3])= 2, a13(data[6])= 3
    // a21(data[1])= 4, a22(data[4])= 5, a23(data[7])= 6
    // a31(data[2])= 7, a32(data[5])= 8, a33(data[8])= 9
    stdout.printf ("Mat3 A\n");
    stdout.printf ("a11=%f a12=%f a13=%f \n", a.data[0], a.data[3],
       a.data[6]);
    stdout.printf ("a21=%f a22=%f a23=%f \n", a.data[1], a.data[4],
       a.data[7]);
    stdout.printf ("a31=%f a32=%f a33=%f \n", a.data[2], a.data[5],
       a.data[8]);
    stdout.printf ("\n");

    var va = Vec3.from_data (1.0f, 2.0f, 3.0f);
    var vb = Vec3.from_data (4.0f, 5.0f, 6.0f);
    a = Mat3.from_vec_mul (ref va, ref vb);
    // a11(data[0])= 4, a12(data[3])= 5, a13(data[6])= 6
    // a21(data[1])= 8, a22(data[4])= 10, a23(data[7])= 12
    // a31(data[2])= 12, a32(data[5])= 15, a33(data[8])= 18
    stdout.printf ("Mat3 A\n");
    stdout.printf ("a11=%f a12=%f a13=%f \n", a.data[0], a.data[3],
       a.data[6]);
    stdout.printf ("a21=%f a22=%f a23=%f \n", a.data[1], a.data[4],
       a.data[7]);
    stdout.printf ("a31=%f a32=%f a33=%f \n", a.data[2], a.data[5],
       a.data[8]);
    stdout.printf ("\n");

    float d_array = {1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f};
    a = Mat3.from_array (d_array);
    // a11(data[0])= 1, a12(data[3])= 4, a13(data[6])= 7
    // a21(data[1])= 2, a22(data[4])= 5, a23(data[7])= 8
    // a31(data[2])= 3, a32(data[5])= 6, a33(data[8])= 9
    stdout.printf ("Mat3 A\n");
    stdout.printf ("a11=%f a12=%f a13=%f \n", a.data[0], a.data[3],
       a.data[6]);
    stdout.printf ("a21=%f a22=%f a23=%f \n", a.data[1], a.data[4],
       a.data[7]);
    stdout.printf ("a31=%f a32=%f a33=%f \n", a.data[2], a.data[5],
       a.data[8]);
    stdout.printf ("\n");

    a = Mat3.identity ();
    // a11(data[0])= 1, a12(data[3])= 0, a13(data[6])= 0
    // a21(data[1])= 0, a22(data[4])= 1, a23(data[7])= 0
    // a31(data[2])= 0, a32(data[5])= 0, a33(data[8])= 1
    stdout.printf ("Mat3 A\n");
    stdout.printf ("a11=%f a12=%f a13=%f \n", a.data[0], a.data[3],
       a.data[6]);
    stdout.printf ("a21=%f a22=%f a23=%f \n", a.data[1], a.data[4],
       a.data[7]);
    stdout.printf ("a31=%f a32=%f a33=%f \n", a.data[2], a.data[5],
       a.data[8]);
    stdout.printf ("\n");
}

実行結果
Mat3 A
a11=0.000000 a12=0.000000 a13=0.000000
a21=0.000000 a22=0.000000 a23=0.000000
a31=0.000000 a32=0.000000 a33=0.000000

Mat3 A
a11=1.000000 a12=2.000000 a13=3.000000
a21=4.000000 a22=5.000000 a23=6.000000
a31=7.000000 a32=8.000000 a33=9.000000

Mat3 A
a11=4.000000 a12=5.000000 a13=6.000000
a21=8.000000 a22=10.000000 a23=12.000000
a31=12.000000 a32=15.000000 a33=18.000000

Mat3 A
a11=1.000000 a12=4.000000 a13=7.000000
a21=2.000000 a22=5.000000 a23=8.000000
a31=3.000000 a32=6.000000 a33=9.000000

Mat3 A
a11=1.000000 a12=0.000000 a13=0.000000
a21=0.000000 a22=1.000000 a23=0.000000
a31=0.000000 a32=0.000000 a33=1.000000


2 ベクトル演算
## prog2
## main.vala
// Mat3 ベクトル演算 1
using ValaGL.Core;

void main () {
    var a = Mat3.from_data (1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f,
       7.0f, 8.0f, 9.0f);
    var b = Mat3.from_data (9.0f, 8.0f, 7.0f, 6.0f, 5.0f, 4.0f,
       3.0f, 2.0f, 1.0f);
    a.add (ref b);
    // a11(data[0])= 10, a12(data[3])= 10, a13(data[6])= 10
    // a21(data[1])= 10, a22(data[4])= 10, a23(data[7])= 10
    // a31(data[2])= 10, a32(data[5])= 10, a33(data[8])= 10
    stdout.printf ("Mat3 A\n");
    stdout.printf ("a11=%f a12=%f a13=%f \n", a.data[0], a.data[3],
       a.data[6]);
    stdout.printf ("a21=%f a22=%f a23=%f \n", a.data[1], a.data[4],
       a.data[7]);
    stdout.printf ("a31=%f a32=%f a33=%f \n", a.data[2], a.data[5],
       a.data[8]);
    stdout.printf ("\n");

    a.sub (ref b);
    // a11(data[0])= 1, a12(data[3])= 2, a13(data[6])= 3
    // a21(data[1])= 4, a22(data[4])= 5, a23(data[7])= 6
    // a31(data[2])= 7, a32(data[5])= 8, a33(data[8])= 9
    stdout.printf ("Mat3 A\n");
    stdout.printf ("a11=%f a12=%f a13=%f \n", a.data[0], a.data[3],
       a.data[6]);
    stdout.printf ("a21=%f a22=%f a23=%f \n", a.data[1], a.data[4],
       a.data[7]);
    stdout.printf ("a31=%f a32=%f a33=%f \n", a.data[2], a.data[5],
       a.data[8]);
    stdout.printf ("\n");

    a.mul (2.0f);
    // a11(data[0])= 2, a12(data[3])= 4, a13(data[6])= 6
    // a21(data[1])= 8, a22(data[4])= 10, a23(data[7])= 12
    // a31(data[2])= 14, a32(data[5])= 16, a33(data[8])= 18
    stdout.printf ("Mat3 A\n");
    stdout.printf ("a11=%f a12=%f a13=%f \n", a.data[0], a.data[3],
       a.data[6]);
    stdout.printf ("a21=%f a22=%f a23=%f \n", a.data[1], a.data[4],
       a.data[7]);
    stdout.printf ("a31=%f a32=%f a33=%f \n", a.data[2], a.data[5],
       a.data[8]);
    stdout.printf ("\n");

    a.div (2.0f);
    // a11(data[0])= 1, a12(data[3])= 2, a13(data[6])= 3
    // a21(data[1])= 4, a22(data[4])= 5, a23(data[7])= 6
    // a31(data[2])= 7, a32(data[5])= 8, a33(data[8])= 9
    stdout.printf ("Mat3 A\n");
    stdout.printf ("a11=%f a12=%f a13=%f \n", a.data[0], a.data[3],
       a.data[6]);
    stdout.printf ("a21=%f a22=%f a23=%f \n", a.data[1], a.data[4],
       a.data[7]);
    stdout.printf ("a31=%f a32=%f a33=%f \n", a.data[2], a.data[5],
       a.data[8]);
    stdout.printf ("\n");

    a.mul_mat (ref b);
    // a11(data[0])= 30, a12(data[3])= 24, a13(data[6])= 18
    // a21(data[1])= 84, a22(data[4])= 69, a23(data[7])= 54
    // a31(data[2])= 138, a32(data[5])= 114, a33(data[8])= 90
    stdout.printf ("Mat3 A\n");
    stdout.printf ("a11=%f a12=%f a13=%f \n", a.data[0], a.data[3],
       a.data[6]);
    stdout.printf ("a21=%f a22=%f a23=%f \n", a.data[1], a.data[4],
       a.data[7]);
    stdout.printf ("a31=%f a32=%f a33=%f \n", a.data[2], a.data[5],
       a.data[8]);
    stdout.printf ("\n");
}

実行結果
Mat3 A
a11=10.000000 a12=10.000000 a13=10.000000
a21=10.000000 a22=10.000000 a23=10.000000
a31=10.000000 a32=10.000000 a33=10.000000

Mat3 A
a11=1.000000 a12=2.000000 a13=3.000000
a21=4.000000 a22=5.000000 a23=6.000000
a31=7.000000 a32=8.000000 a33=9.000000

Mat3 A
a11=2.000000 a12=4.000000 a13=6.000000
a21=8.000000 a22=10.000000 a23=12.000000
a31=14.000000 a32=16.000000 a33=18.000000

Mat3 A
a11=1.000000 a12=2.000000 a13=3.000000
a21=4.000000 a22=5.000000 a23=6.000000
a31=7.000000 a32=8.000000 a33=9.000000

Mat3 A
a11=30.000000 a12=24.000000 a13=18.000000
a21=84.000000 a22=69.000000 a23=54.000000
a31=138.000000 a32=114.000000 a33=90.000000


3 ベクトル演算2
## prog3
## main.vala
// Mat3 ベクトル演算 2
using ValaGL.Core;

void main () {
    var a = Mat3.from_data (2.0f, -2.0f, 3.0f, 1.0f, 1.0f, 1.0f,
       1.0f, 3.0f, -1.0f);
    var va = Vec3.from_data (1.0f, 2.0f, 3.0f);

    //Vec3 mul_vec (ref Vec3 vec)
    Vec3 vb = a.mul_vec (ref va);
    // vb.x = 7, vb.y = 6, vb.z = 4
    stdout.printf ("Vec3 vb\n");
    stdout.printf ("vb.x=%f vb.y=%f vb.z=%f \n", vb.x, vb.y, vb.z);
    stdout.printf ("\n");

    //Mat3 transposed ()
    Mat3 b = a.transposed ();
    // b11(data[0])= 2, b12(data[3])= 1, b13(data[6])= 1
    // b21(data[1])= -2, b22(data[4])= 1, b23(data[7])= 3
    // b31(data[2])= 3, b32(data[5])= 1, b33(data[8])= -1
    stdout.printf ("Mat3 B\n");
    stdout.printf ("b11=%f b12=%f b13=%f \n", b.data[0], b.data[3],
       b.data[6]);
    stdout.printf ("b21=%f b22=%f b23=%f \n", b.data[1], b.data[4],
       b.data[7]);
    stdout.printf ("b31=%f b32=%f b33=%f \n", b.data[2], b.data[5],
       b.data[8]);
    stdout.printf ("\n");

    //GLfloat det ()
    float det = a.det ();
    // det = -6
    stdout.printf ("float Det\n");
    stdout.printf ("det =%f\n", det);
    stdout.printf ("\n");

    //Mat3 inverted (out bool success)
    bool success;
    b = a.inverted (out success);
    // success
    // b11(data[0])= 4/6, b12(data[3])= -7/6, b13(data[6])= 5/6
    // b21(data[1])= -2/6, b22(data[4])= 5/6, b23(data[7])= -1/6
    // b31(data[2])= -2/6, b32(data[5])= 8/6, b33(data[8])= -4/6
    // not success
    // b11(data[0])= 0, b12(data[3])= 0, b13(data[6])= 0
    // b21(data[1])= 0, b22(data[4])= 0, b23(data[7])= 0
    // b31(data[2])= 0, b32(data[5])= 0, b33(data[8])= 0
    stdout.printf ("Mat3 B\n");
    if (success == false) {stdout.printf ("not success\n");}
    else {stdout.printf ("success\n");}
    stdout.printf ("b11=%f b12=%f b13=%f \n", b.data[0], b.data[3],
       b.data[6]);
    stdout.printf ("b21=%f b22=%f b23=%f \n", b.data[1], b.data[4],
       b.data[7]);
    stdout.printf ("b31=%f b32=%f b33=%f \n", b.data[2], b.data[5],
       b.data[8]);
}

実行結果
Vec3 vb
vb.x=7.000000 vb.y=6.000000 vb.z=4.000000

Mat3 B
b11=2.000000 b12=1.000000 b13=1.000000
b21=-2.000000 b22=1.000000 b23=3.000000
b31=3.000000 b32=1.000000 b33=-1.000000

float Det
det =-6.000000

Mat3 B
success
b11=0.666667 b12=-1.166667 b13=0.833333
b21=-0.333333 b22=0.833333 b23=-0.166667
b31=-0.333333 b32=1.333333 b33=-0.666667


ビルド
valac --vapidir=./ --pkg glepoxy -X -lm main.vala MatrixMath.vala