コガネブログ

平日更新を目標にUnityやC#、Visual Studioなどのゲーム開発アレコレを書いていきます

【Unity】ベジェ曲線のプログラム

using UnityEngine;

/// <summary>
/// Mathf クラスに関する汎用関数を管理するクラス
/// </summary>
public static class MathfUtils
{
    /// <summary>
    /// ベジェ曲線における X 座標を返します
    /// </summary>
    /// <remarks>http://opentype.jp/fontguide_doc3.htm</remarks>
    /// <param name="x1">開始点の X 座標</param>
    /// <param name="x2">制御点 1 の X 座標</param>
    /// <param name="x3">制御点 2 の X 座標</param>
    /// <param name="x4">終点の X 座標</param>
    /// <param name="t">重み(0 から 1)</param>
    /// <returns>ベジェ曲線における X 座標</returns>
    public static float BezierCurveX(float x1, float x2, float x3, float x4, float t)
    {
        return Mathf.Pow(1 - t, 3) * x1 + 3 * Mathf.Pow(1 - t, 2) * t * x2 + 3 * (1 - t) * Mathf.Pow(t, 2) * x3 + Mathf.Pow(t, 3) * x4;
    }

    /// <summary>
    /// ベジェ曲線における Y 座標を返します
    /// </summary>
    /// <remarks>http://opentype.jp/fontguide_doc3.htm</remarks>
    /// <param name="y1">開始点の Y 座標</param>
    /// <param name="y2">制御点 1 の Y 座標</param>
    /// <param name="y3">制御点 2 の Y 座標</param>
    /// <param name="y4">終点の Y 座標</param>
    /// <param name="t">重み(0 から 1)</param>
    /// <returns>ベジェ曲線における Y 座標</returns>
    public static float BezierCurveY(float y1, float y2, float y3, float y4, float t)
    {
        return Mathf.Pow(1 - t, 3) * y1 + 3 * Mathf.Pow(1 - t, 2) * t * y2 + 3 * (1 - t) * Mathf.Pow(t, 2) * y3 + Mathf.Pow(t, 3) * y4;
    }
    
    /// <summary>
    /// ベジェ曲線における 2 次元座標を返します
    /// </summary>
    /// <param name="p1">開始点の座標</param>
    /// <param name="p2">制御点 1 の座標</param>
    /// <param name="p3">制御点 2 の座標</param>
    /// <param name="p4">終点の座標</param>
    /// <param name="t">重み(0 から 1)</param>
    /// <returns>B-スプライン曲線における 2 次元座標</returns>
    public static Vector2 BezierCurve(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, float t)
    {
        return new Vector2(
            BezierCurveX(p1.x, p2.x, p3.x, p4.x, t), 
            BezierCurveY(p1.y, p2.y, p3.y, p4.y, t));
    }
}