【Unity】【C#】範囲を指定できる Mathf.Repeat 
2020/12/20 Sun [edit]
今回は数学的な関数のちょっとした便利拡張メソッド。
Unity においては、特に角度の計算に Mathf.Repeat() はよく使う。例えば入力された値(角度)を -180~180 度に収めたいなどの時だ。
しかし、標準の Mathf.Repeat() では引数が元の値(t)と長さ(length)[=最大(を含まない)] なので、0~max(を含まない) の計算となる。なので、0~360(359) 度などには良いが、0 以外の開始値だと少し不便だったりする。
そこで、Mathf.Repeat() に少し手を加えて、-180~180(を含まない) または -180~180(を含む) のような、範囲内を返せる2つの拡張メソッドを作っておこう。
ちなみに Mathf クラスは C# 標準の Math クラスの軽量版で、C# 標準が double の計算に対して、Unity では float で計算するものと考えて良い。要するに精度より速度を優先したものである。なので、高い計算精度が欲しいときは Math クラスを使った方が良いだろう(当然処理速度は重くなるので注意)。
(※) Unity 2019.4 / Windows10(x64) で確認 (※バージョン依存はないと思う)
●下限~上限(を含まない)範囲を返す Mathf.Repeat
using UnityEngine;
public static class MathfExtentions //※クラス名は任意
{
/// <summary>
/// 下限~上限(を含まない)範囲を返す Mathf.Repeat
/// 2020/12/20 Fantom
/// http://fantom1x.blog130.fc2.com/blog-entry-390.html
/// </summary>
/// <param name="value">元の値</param>
/// <param name="min">下限 (inclusive)</param>
/// <param name="max">上限 (exclusive)</param>
/// <returns>min(inclusive)~max(exclusive) の Mathf.Repeat</returns>
public static float Repeat(this float value, float min, float max)
{
return Mathf.Repeat(value - min, max - min) + min;
}
//int 版
public static int Repeat(this int value, int min, int max)
{
return (int)Mathf.Repeat(value - min, max - min) + min;
}
}
●メインコード例
using UnityEngine;
using System.Text;
var sb = new StringBuilder(1024);
for (int i = -45; i <= 45; i++)
{
var x = i.Repeat(-45, 45);
if (sb.Length > 0)
sb.Append(", ");
sb.Append(x);
}
Debug.Log(sb.ToString());
注意点としては、値の上限(max)を「含まない」という点だ。
この例の場合、max = 45 のため「…, 43, 44, -45, -44, …」のように値がループする。
●下限~上限(を含む)範囲を返す Mathf.Repeat
)範囲を返す Mathf.Repeat
using UnityEngine;
public static class MathfExtentions //※クラス名は任意
{
/// <summary>
/// 下限~上限(を含む)範囲を返す Mathf.Repeat
/// 2020/12/20 Fantom
/// http://fantom1x.blog130.fc2.com/blog-entry-390.html
/// </summary>
/// <param name="value">元の値</param>
/// <param name="min">下限 (inclusive)</param>
/// <param name="max">上限 (inclusive)</param>
/// <returns>min(inclusive)~max(inclusive) の Mathf.Repeat</returns>
public static float RepeatInclusive(this float value, float min, float max)
{
return (value == max) ? max : Repeat(value, min, max); //※「下限~上限(を含まない)」関数が必要
}
//int 版
public static int RepeatInclusive(this int value, int min, int max)
{
return (value == max) ? max : Repeat(value, min, max);
}
}
●メインコード例
using UnityEngine;
using System.Text;
var sb = new StringBuilder(1024);
for (int i = -45; i <= 45; i++)
{
var x = i.RepeatInclusive(-45, 45);
if (sb.Length > 0)
sb.Append(", ");
sb.Append(x);
}
Debug.Log(sb.ToString());
注意点としては、値の上限(max)を「含む」という点だ。関数内部で前述の「下限~上限(を含まない)」版も利用している。
この例の場合、max = 45 のため「…, 43, 44, 45, -44, …」のように値がループする。
また、値の意味としては「-45 と 45 は同値扱い」となる。これは我々の感覚として「-180度 と 180 度が同じ」のように使えるわけで、特に UI において、ユーザーから値を指定してもらう際には便利になる(-180~179 度でも良いが、-180~180 度の方が、人の感覚としてはわかり易い)。
UI の実例としてはスライダー等に使うとわかり易いね。大したものではないが、意外と利用頻度は高いと思う。
|
3D 背景モデル:Floating Island of the Potion Brewer / @vilmariina
360度画像:++skies;008 / @aokcub
(関連記事)
【Unity】【C#】倍数での Floor, Ceil, Round(一定間隔での切り捨て、切り上げ、四捨五入) [float 版]
【C#】最大公約数を求める/分数の約分をする(ユークリッドの互除法)
【Java】最大公約数・最小公倍数を求める(ユークリッドの互除法)
【Java】3つ以上の最大公約数を求める(ユークリッドの互除法②)
【Java】拡張ユークリッドの互除法
- 関連記事
トラックバック
トラックバックURL
→http://fantom1x.blog130.fc2.com/tb.php/390-86e80a8c
この記事にトラックバックする(FC2ブログユーザー)
| h o m e |