ヽ|∵|ゝ(Fantom) の 開発blog? ホーム » Unity »【Unity】【C#】n度ごとの角度を返す(一定角度ごとの切り捨て、切り上げ、四捨五入)

【Unity】【C#】n度ごとの角度を返す(一定角度ごとの切り捨て、切り上げ、四捨五入)  


 今回は「一番近い45・90度ごとの角度を求める」などをやってみよう。これは前回の 「倍数での Floor, Ceil, Round」と内容的には同じものだが、値に0~360度の制限を付けて角度専用にしたものである。一定角度ごとの切り捨て、切り上げ、四捨五入することにより、例えば自由な角度から一番近い東西南北の角度(0, 90, 180, 270度など)に回転させる、なんてことが簡単にできる。もちろん前回の「MultipleFloor, MultipleCeil, MultipleRound」でも構わないが、角度の計算は利用頻度が高いので、専用関数として作っておいた方が何かと楽だろう。



(※) Unity 5.6.1p3 / Windows10(x64) で確認

●一定角度ごとの切り捨て、切り上げ、四捨五入をする(一番近いn度ごとの角度を求める)
using System;

/// <summary>
/// より小さいn度ごとの角度を返す(倍数で切り捨てられるような角度)
///※360度は超えない
///(例)AngleFloor(185, 90) → 180
/// </summary>
/// <param name="angle">入力(度)</param>
/// <param name="width">回転幅(度)</param>
/// <returns>n度で切り捨てた角度</returns>
public static float AngleFloor(float angle, float width)
{
return Mathf.Repeat(Mathf.Floor(angle / width) * width, 360f);
}

/// <summary>
/// より大きいn度ごとの角度を返す(倍数で繰り上がるような角度)
///※360度は超えない
///(例)AngleCeil(185, 90) → 270
/// </summary>
/// <param name="angle">入力(度)</param>
/// <param name="width">回転幅(度)</param>
/// <returns>n度で切り上げた角度</returns>
public static float AngleCeil(float angle, float width)
{
return Mathf.Repeat(Mathf.Ceil(angle / width) * width, 360f);
}

/// <summary>
/// n度ごとの四捨五入のような角度を返す(n/2度で四捨五入のような角度)
///※360度は超えない
///(例)AngleRound(134, 90) → 90, AngleRound(135, 90) → 180
/// </summary>
/// <param name="angle">入力(度)</param>
/// <param name="width">回転幅(度)</param>
/// <returns>n度の中間の値で切り捨て・切り上げした角度</returns>
public static float AngleRound(float angle, float width)
{
return Mathf.Repeat(AngleFloor(angle + width * 0.5f, width), 360f);
}

(例)angle を45度おきに切り捨てる
 AngleFloor(angle, 45) : 54, 192, 325 → 45, 180, 315
(例)angle を90度おきに切り捨てる
 AngleFloor(angle, 90) : 54, 192, 325 → 0, 180, 270

(例)angle を45度おきに切り上げる
 AngleCeil(angle, 45) : 54, 192, 325 → 90, 225, 0
(例)angle を90度おきに切り上げる
 AngleCeil(angle, 90) : 54, 192, 325 → 90, 270, 0

(例)angle を45度おきに切り捨て・切り上げる(45の中間の22.5を閾値として切り捨て・切り上げをする:22.4→0, 22.5→45)
 AngleRound(angle, 45) : 54, 192, 325 → 45, 180, 315
(例)angle を90度おきに切り捨て・切り上げる(90の中間の45を閾値として切り捨て・切り上げをする:44→0, 45→90)
 AngleRound(angle, 90) : 54, 192, 325 → 90, 180, 0

 1つだけ注意点は AngleRound() に関しては、関数内部で AngleFloor() を使っている点だ。これは C# の Mathf.Round() の丸め方はどちらかと言うと五捨六入に近いので、他の言語に移植などするとき、そのままでは結果が異なってしまうため、Round(v) の代わりに Floor(v + 0.5) を使っている。他の言語との Round の値の違いは以下のページの一覧やフォーラムなどを参照して欲しい。

Java, C#, PHP, Ruby, Python, JavaScript での Math.round(四捨五入・五捨六入)比較
Math.Roundって五捨六入?

 スマホアプリなどのスワイプ(フリック)動作に利用すれば、指でくるっとカメラを90度回転など簡単に実装できる。スマホなど指で操作するものなどはきっちりとした角度にするのは難しいので、こうした角度補正などを付けてあげると、操作性も上がり気持ちの良い動作になったりもする。応用範囲は広いので色々使ってみると良いだろう。

実は画面をスワイプすると、カメラがキャラの廻りをぐるりと90度ごと回転して
眺められるようになっている(※ただし、このゲームには特に必要ない機能(笑))。
>> PronamaChan in Action Game!(Android 版)



(関連記事)
【Unity】【C#】倍数での Floor, Ceil, Round(一定間隔での切り捨て、切り上げ、四捨五入) [float 版]
【Unity】【C#】符号(方向)付き角度を、2Dの外積を使って求める [2D]
【Unity】【C#】床面(Yaw)/YZ平面(Pitch)に射影された角度を、符号(方向)付きで求める [3D]


スポンサーサイト

category: Unity

thread: ゲーム開発

janre: コンピュータ

tag: Unityライブラリ  C# 
tb: 0   cm: --


トラックバック

トラックバックURL
→http://fantom1x.blog130.fc2.com/tb.php/249-0787b4e1
この記事にトラックバックする(FC2ブログユーザー)

プロフィール

検索フォーム

全記事一覧

カテゴリ

ユーザータグ

最新記事

リンク

PR

▲ Pagetop