三途の川おさかなのブログ

だらだらしている

MoveTowardsAngleの実装

朝7時ごろに起きた。出社の時間までプログラミング。
MoveTowardsAngle の実装を書いてみた。

// a を b に maxDelta の範囲で近づけた値を得る.
public static float MoveTowards(float a, float b, float maxDelta) {
  var toB = b - a;
  var delta = (toB < 0) ?
    System.Math.Max(toB, -maxDelta) :
    System.Math.Min(toB, maxDelta);
  return a + delta;
}

// 角度を [ 0 <= x < 360 ] の範囲に収める.
public static float NormalizeAngle360(float a) {
  if (a < 0f) {
    if (-360f < a) {
      return 360f + a;
    } else {
      return 360f + (a % 360f);
    }
  } else {
    if (a < 360f) {
      return a;
    } else {
      return a % 360f;
    }
  }
}

// a を b に maxDelta の範囲で近づけた角度を得る..
// 得られる角度は [ 0 <= x < 360 ] の範囲.
public static float MoveTowardsAngle(float a, float b, float maxDelta) {
  // 正規化
  a = NormalizeAngle360(a);
  b = NormalizeAngle360(b);
  
  float toB = b - a;
  if (180f < toB) {
    return NormalizeAngle360(MoveTowards(a + 360f, b, maxDelta));
  } else if (toB < -180f) {
    return NormalizeAngle360(MoveTowards(a, b + 360f, maxDelta));
  } else {
    return MoveTowards(a, b, maxDelta);
  }
}

ひとつの関数で完結させようとするとゴチャるので MoveTowards, NormalizeAngle360 関数に処理を逃した。
MoveTowardsAngles 自体はシンプルに書けたと思う。
このパーツに分割して組み立てるのはプラモ感があって気持ち良い。

// a を b に maxDelta の範囲で近づけた角度を得る..
// 得られる角度は [ 0 <= x < 360 ] の範囲.
public static float MoveTowardsAngle(float a, float b, float maxDelta) {
  // 正規化
  a = NormalizeAngle360(a);
  b = NormalizeAngle360(b);
  
  float toB = b - a;
  if (180f < toB) {
    return NormalizeAngle360(MoveTowards(a + 360f, b, maxDelta));
  } else if (toB < -180f) {
    return NormalizeAngle360(MoveTowards(a, b + 360f, maxDelta));
  } else {
    return MoveTowards(a, b, maxDelta);
  }
}

角度を0から360に丸める NormalizeAngle360 関数。-720度とか2回転以上の度数も考えようとすると混乱する。

// 角度を [ 0 <= x < 360 ] の範囲に収める.
public static float NormalizeAngle360(float a) {
  if (a < 0f) {
    if (-360f < a) {
      return 360f + a;
    } else {
      return 360f + (a % 360f);
    }
  } else {
    if (a < 360f) {
      return a;
    } else {
      return a % 360f;
    }
  }
}

1行で、こう書いても良い。

// 角度を [ 0 <= x < 360 ] の範囲に収める.
public static float NormalizeAngle360(float a) {
  return (360f + (a % 360f)) % 360f;
}

ここではいらないけど、角度を -180 から 180 の範囲に丸める NormalizeAngle180 も欲しくなる。
正規化。ノーマライズって言うとかっこいい。

ブラウザで動作確認 - https://paiza.io/projects/95Enu3ZMwu8liGl5TLd5ZQ

3時間近くかかってしまった。
思ってた以上に、頭が混乱した。
昨日5分で書こうと頭の中で考えてたコードが間違ってて、一回書き直したりしてた。
とはいえ、楽しんで書けました。おしまい。

朝 ミロ
油そば
晩 ナスと鶏肉炒め
体重 59.4Kg