Vala プログラミング

WebGPU プログラミング

おなが@京都先端科学大

Vala OpenGL ( ValaGL MatrixMath.vala )

ValaGL MatrixMath.vala の演算

前回のブログで使用した、ValaGL MatrixMath.vala の演算について書いています。

 

今回は、Vec3 ( 3次元ベクトル)です。

 

Vec3の定義

struct Vec3

   メンバー
   GLfloat data[3]

   メソッド
  * 生成
   Vec3()
        要素が 0 値の Vec3 を生成
        ( Creates a new vector, zero initialized. )

   Vec3.from_data (GLfloat x, GLfloat y, GLfloat z)
        要素が {x, y, z} Vec3 を生成
       ( Creates a vector whose contents are the copy of the given data. )

   Vec3.from_array (GLfloat data)
        要素が配列 data で与えられる Vec3 を生成
       ( Creates a vector whose contents are the copy of the given array. )

* 要素間の演算
   void add (ref Vec3 other)
       this
インスタンス)と other ベクトルとの和(要素間の和)
       ( Adds the given vector, component-wise. )

   void sub (ref Vec3 other)
       this
インスタンス)から other ベクトルを引く(要素間の差)
       ( Subtracts the given vector, component-wise. )

   void mul_vec (ref Vec3 other)
       this(インスタンス)と other ベクトルの積(要素間の積)
      ( Multiplies the given vector, component-wise. )

   void div_vec (ref Vec3 other)
      this(インスタンス)を other ベクトルで割る(要素間の商) 
      ( Divides the given vector, component-wise. )

   * ベクトル演算
   GLfloat dot_product (ref Vec3 other)
      this(インスタンス)と other ベクトルの内積
      ( Computes the dot product of this vector and the other vector. )

   Vec3 cross_product (ref Vec3 other)
      this(インスタンス)と other ベクトルの外積(thisベクトル ✖️ otherベクトル)
      ( Computes the cross product of this vector and the other vector. )

   void mul (GLfloat factor)
      this(インスタンス)の各要素をfactor倍する 
      ( Multiplies the vector by the given scalar. )

   void div (GLfloat factor)
      this(インスタンス)の各要素をfactorで割る
      ( Divides the vector by the given scalar. )

   GLfloat norm ()
      this(インスタンス)ベクトルの大きさを求める
     ( Computes the norm of this vector. )

   void normalize ()
      this(インスタンス)ベクトルを規格化する
     ( Normalizes this vector, dividing it by its norm.
       If the norm is zero, the result is undefined. )

  *アクセッサー(ゲッター)
  GLfloat x
       data[0]へのアクセッサー
       ( Convenience accessor for data[0]. )

  GLfloat y
       data[1]へのアクセッサー
      ( Convenience accessor for data[1]. )

GLfloat z
       data[2]へのアクセッサー
      ( Convenience accessor for data[2]. )

 

1 ベクトルの生成

## prog1.vala
using ValaGL.Core;

void main () {
    var a = Vec3 ();
    // a.data[0] = 0,  a.data[1] = 0,  a.data[2] = 0
    stdout.printf ("Vec3 a x:%f y:%f z:%f\n", a.data[0], a.data[1], a.data[2]);
    stdout.printf("\n");

    var b = Vec3.from_data (1.0f, 2.0f, 3.0f);
    // b.x(data[0]) = 1.0,  b.y(data[1]) = 2.0,  b.z(data[2]) = 3.0
    stdout.printf ("Vec3 b x:%f y:%f z:%f\n", b.data[0], b.data[1], b.data[2]);
    stdout.printf ("Vec3 b x:%f y:%f z:%f\n", b.x, b.y, b.z);
    stdout.printf("\n");

    float
d = {4.0f, 5.0f, 6.0f};
    var c = Vec3.from_array (d);
    // c.x = 4.0,  c.y = 5.0,  c.z = 6.0
    stdout.printf ("Vec3 c x:%f y:%f z:%f\n", c.x, c.y, c.z);
}

 

実行結果
Vec3 a x:0.000000 y:0.000000 z:0.000000

Vec3 b x:1.000000 y:2.000000 z:3.000000
Vec3 b x:1.000000 y:2.000000 z:3.000000

Vec3 c x:4.000000 y:5.000000 z:6.000000

 

2 要素間の演算

## prog2.vala
using ValaGL.Core;

void main () {
    var a = Vec3.from_data (4.0f, 5.0f, 6.0f);
    stdout.printf ("Vec3 a x:%f y:%f z:%f\n", a.x, a.y, a.z);
    var b = Vec3.from_data (1.0f, 2.0f, 3.0f);
    stdout.printf ("Vec3 b x:%f y:%f z:%f\n", b.x, b.y, b.z);
    stdout.printf("\n");

    a.add (ref b);
    // a.x = a.x + b.x,  a.y = a.y + b.y,  a.z = a.z + b.z
    stdout.printf ("Vec3 a x:%f y:%f z:%f\n", a.x, a.y, a.z);
    stdout.printf("\n");

    a.sub (ref b);
    // a.x = a.x - b.x,  a.y = a.y - b.y,  a.z = a.z - b.z
    stdout.printf ("Vec3 a x:%f y:%f z:%f\n", a.x, a.y, a.z);
    stdout.printf("\n");

    a.mul_vec (ref b);
    // a.x = a.x * b.x,  a.y = a.y * b.y,  a.z = a.z * b.z
    stdout.printf ("Vec3 a x:%f y:%f z:%f\n", a.x, a.y, a.z);
    stdout.printf("\n");


    a.div_vec (ref b);
    // a.x = a.x / b.x,  a.y = a.y / b.y,  a.z = a.z / b.z
    stdout.printf ("Vec3 a x:%f y:%f z:%f\n", a.x, a.y, a.z);
    stdout.printf("\n");
}

 

実行結果
Vec3 a x:4.000000 y:5.000000 z:6.000000
Vec3 b x:1.000000 y:2.000000 z:3.000000

Vec3 a x:5.000000 y:7.000000 z:9.000000

Vec3 a x:4.000000 y:5.000000 z:6.000000

Vec3 a x:4.000000 y:10.000000 z:18.000000

Vec3 a x:4.000000 y:5.000000 z:6.000000

 

3 ベクトル演算

## prog3.vala
using ValaGL.Core;

void main () {
    var a = Vec3.from_data (4.0f, 5.0f, 6.0f);
    stdout.printf ("Vec3 a x:%f y:%f z:%f\n", a.x, a.y, a.z);
    var b = Vec3.from_data (1.0f, 2.0f, 3.0f);
    stdout.printf ("Vec3 b x:%f y:%f z:%f\n", b.x, b.y, b.z);
    stdout.printf("\n");

    float s = a.dot_product (ref b);
    // s = a.x*b.x + a.y*b.y + a.z*b.z
    stdout.printf("s: %f\n", s);
    stdout.printf("\n");

    Vec3 c = a.cross_product (ref b);
    // c.x = a.y*b.z - a.z*b.y,  c.y = a.z*b.x - a.x*b.z,  c.z = a.x*b.y - a.y*b.x
    stdout.printf ("Vec3 c x:%f y:%f z:%f\n", c.x, c.y, c.z);
    stdout.printf("\n");

    a.mul (2);
    // a.x = a.x * 2,  a.y = a.y * 2,  a.z = a.z * 2
    stdout.printf ("Vec3 a x:%f y:%f z:%f\n", a.x, a.y, a.z);
    stdout.printf("\n");

    a.div (2);
    // a.x = a.x / 2,  a.y = a.y / 2,  a.z = a.z / 2
    stdout.printf ("Vec3 a x:%f y:%f z:%f\n", a.x, a.y, a.z);
    stdout.printf("\n");

    float b_norm = b.norm ();
    // b_norm = SQRT( b.x*b.x + b.y*b.y + b.z*b.z)
    stdout.printf ("norm b : %f\n", b_norm);
    stdout.printf("\n");

    b.normalize ();
    // b.x = b.x / b.norm(),  b.y = b.y / b.norm(),   b.z = b.z / b.norm()
    stdout.printf ("b x:%f y:%f z:%f\n", b.x, b.y, b.z);
    stdout.printf ("b norm = %f\n", b.norm());
    stdout.printf("\n");
}

 

実行結果
Vec3 a x:4.000000 y:5.000000 z:6.000000
Vec3 b x:1.000000 y:2.000000 z:3.000000

s: 32.000000

Vec3 c x:3.000000 y:-6.000000 z:3.000000

Vec3 a x:8.000000 y:10.000000 z:12.000000

Vec3 a x:4.000000 y:5.000000 z:6.000000

norm b : 3.741657

b x:0.267261 y:0.534522 z:0.801784
b norm = 1.000000

 

*ビルド
valac --vapidir=./ --pkg glepoxy -X -lm prog1.vala MatrixMath.vala
( glepoxy.vapi も必要)