Toshihiro Shimizu 890ddd
// #include <iostream></iostream>
Toshihiro Shimizu 890ddd
#include <cmath> /* pow(), ceil() */</cmath>
Toshihiro Shimizu 890ddd
#include "igs_motion_wind_table.h"
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int igs::motion_wind::table_size(const double length_min,
Shinya Kitaoka 120a6e
                                 const double length_max) {
Shinya Kitaoka 120a6e
  if (length_min < length_max) {
Shinya Kitaoka 120a6e
    return static_cast<int>(ceil(length_max));</int>
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return static_cast<int>(ceil(length_min));</int>
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*
Toshihiro Shimizu 890ddd
引数の(3つの)ランダムクラスは別々でもいいし、同じものでもいい。
Toshihiro Shimizu 890ddd
別々でシード値を同じにすればlength,force,densityの3つとも
Toshihiro Shimizu 890ddd
同じランダム列にすることができる。
Toshihiro Shimizu 890ddd
同じクラスを使う場合は、length,force,densityを混ぜてランダムになる。
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
int igs::motion_wind::make_table(
Shinya Kitaoka 120a6e
    std::vector<double> &table, igs::math::random &length_random,</double>
Shinya Kitaoka 120a6e
    igs::math::random &force_random, igs::math::random &density_random,
Shinya Kitaoka 120a6e
    const double length_min, const double length_max,
Shinya Kitaoka 120a6e
    const double length_bias  // 0<...1...
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    const double force_min, const double force_max,
Shinya Kitaoka 120a6e
    const double force_bias  // 0<...1...
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    const double density_min, const double density_max,
Shinya Kitaoka 120a6e
    const double density_bias  // 0<...1...
Shinya Kitaoka 120a6e
    ) {
Shinya Kitaoka 120a6e
  /* length_minと、length_maxが同じ値なら固定長 */
Shinya Kitaoka 120a6e
  double length = length_min;
Shinya Kitaoka 120a6e
  if (length_min != length_max) {        /* minとmaxの間でrandomな長さ */
Shinya Kitaoka 120a6e
    double dif = length_random.next_d(); /* 0...1 */
Shinya Kitaoka 120a6e
    if (0.0 != length_bias) {            /* 長さの片寄り */
Shinya Kitaoka 120a6e
      dif = pow(dif, 1.0 / length_bias);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    length += dif * (length_max - length_min); /* 実際の長さ */
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  // std::cout << "l " << length;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  /* force_minと、force_maxが同じ値なら固定カーブ */
Shinya Kitaoka 120a6e
  double force = force_min;
Shinya Kitaoka 120a6e
  if (force_min != force_max) { /* minとmaxの間でrandomなカーブ */
Shinya Kitaoka 120a6e
    double dif = force_random.next_d(); /* 0...1 */
Shinya Kitaoka 120a6e
    if (0.0 != force_bias) {            /* カーブの片寄り */
Shinya Kitaoka 120a6e
      dif = pow(dif, 1.0 / force_bias);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    force += dif * (force_max - force_min); /* 実際のカーブ値 */
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  // std::cout << "  c " << force;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  /* density_minと、density_maxが同じ値なら固定高さ */
Shinya Kitaoka 120a6e
  double density = density_min;
Shinya Kitaoka 120a6e
  if (density_min != density_max) { /* minからmaxの間でrandomな高 */
Shinya Kitaoka 120a6e
    double dif = density_random.next_d(); /* 0...1 */
Shinya Kitaoka 120a6e
    if (0.0 != density_bias) {            /* 高さの片寄り */
Shinya Kitaoka 120a6e
      dif = pow(dif, 1.0 / density_bias);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    density += dif * (density_max - density_min); /* 実際の高さ値 */
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  // std::cout << "  h " << density << "\n";
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  const int table_len = static_cast<int>(ceil(length));</int>
Shinya Kitaoka 120a6e
  /* 長さ:リニア減衰列を設定する
Shinya Kitaoka 120a6e
          table.at[0]          [1]            [2]
Shinya Kitaoka 120a6e
  length	ii
Shinya Kitaoka 120a6e
  3.0 --> 3 -->	1.0(3.0/3.0) 0.666(2.0/3.0) 0.333(1.0/3.0)
Shinya Kitaoka 120a6e
  2.5 --> 3 -->	1.0(2.5/2.5) 0.6(1.5/2.5)   0.2(0.5/2.5)
Shinya Kitaoka 120a6e
  2.0 --> 2 -->	1.0(2.0/2.0) 0.5(1.0/2.0)   [0.0(0.0/1.5)]
Shinya Kitaoka 120a6e
  1.5 --> 2 -->	1.0(1.5/1.5) 0.333(0.5/1.5) [-0.333(-0.5/1.5)]
Shinya Kitaoka 120a6e
  1.0 --> 1 -->	1.0(1.0/1.0) [0.0(0.0/1.0)]
Shinya Kitaoka 120a6e
  */
Shinya Kitaoka 120a6e
  for (int ii = 0; ii < table_len; ++ii) {
Shinya Kitaoka 120a6e
    table.at(ii) = (length - ii) / length;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  /* 勢い:ガンマ計算によりカーブを設定する */
Shinya Kitaoka 120a6e
  if (1.0 != force) { /* 変化のないとき(1のとき)は動作しない */
Shinya Kitaoka 120a6e
    if (0.0 < force) {
Shinya Kitaoka 120a6e
      for (int ii = 1; ii < table_len; ++ii) {
Shinya Kitaoka 120a6e
        table.at(ii) = pow(table.at(ii), 1.0 / force);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    } else { /* ゼロ以下はゼロを設定する */
Shinya Kitaoka 120a6e
      for (int ii = 1; ii < table_len; ++ii) {
Shinya Kitaoka 120a6e
        table.at(ii) = 0.0;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  /* 濃さ:(高さ)の制御 */
Shinya Kitaoka 120a6e
  for (int ii = 1; ii < table_len; ++ii) {
Shinya Kitaoka 120a6e
    table.at(ii) *= density;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return table_len;
Toshihiro Shimizu 890ddd
}