スピログラフ(Spirograph)を作ってみた


くるりん定規
 Unityでスピログラフ*1作ってみました。


式は、
\(x = (r_{1}-r_{2})cos(\theta) +r_{3}cos(\frac{r_{1}-r_{2}}{r_{2}}\theta) \)
\(y = (r_{1}-r_{2})sin(\theta) -r_{3}sin(\frac{r_{1}-r_{2}}{r_{2}}\theta) \)
こんな感じです。
スライダは上から\(r_{1},r_{2},r_{3}\)になっていて、
左端が-2,右端が2になっています。初期値は確か0のはず(たぶん)。



 \(r_{3}\)を動かすと、うにょうにょと変化して面白いですね。


using UnityEngine;
using System.Collections;

public class MakeLine : MonoBehaviour {

    LineRenderer lR;

    //頂点の再計算フラグ
    bool recal = false;

    //Lineの頂点数
    int vCount = 3600;

    //角回転量
    float angle;

    #region Sliders value
    float v1 = 1.0f;
    float v2 = 1.0f;
    float v3 = 1.0f;
    float v4 = 1.0f;
    #endregion

    // Use this for initialization
	void Start () {
        this.Initialize();
	}
	
	// Update is called once per frame
	void Update () {
        if (this.recal)
        {
            this.SetVertex();
            this.recal = false;A
        }
	
	}

    //初期化
    private void Initialize()
    {
        this.angle = Mathf.PI / (90.0f-1.0f);

        this.lR = this.GetComponent<LineRenderer>();

        this.lR.SetVertexCount(this.vCount);

        this.recal = true;
    }

    private void SetVertex()
    {
        float t1 = v1 - v2;
        float t2 = 10.0f;
        if (v2 != 0) t2 = (v1 - v2) / v2;

        for (int i = 0; i < this.vCount; i++)
        {
            float av = this.angle * i;
            float x = t1 * Mathf.Cos(av) + v3 * Mathf.Cos(t2 * av);
            float y = 1;
            float z = t1 * Mathf.Sin(av) - v3 * Mathf.Sin(t2 * av);

            x = x * 3.0f;
            z = z * 3.0f;

            this.lR.SetPosition(i, new Vector3(x, y, z));
        }
    }

    #region Get sliders value
    //スライダーの値取得
    public void getSlider1Value(float v)
    {
        v1 = v;
        this.recal = true;
    }

    public void getSlider2Value(float v)
    {
        v2 = v;
        this.recal = true;
    }

    public void getSlider3Value(float v)
    {
        v3 = v;
        this.recal = true;
    }

    public void getSlider4Value(float v)
    {
        v4 = v;
        this.recal = true;
    }
    #endregion
}