The Binary Scan

提供: socialakiba wiki
移動: 案内検索

WebGL版 マウス移動とホイール回転で操作します。

ソースコード

using UnityEngine;

public class biscan : MonoBehaviour {
    private int x0, y0;
    private Material mat;
    private const int margin = 10;
    private int segmentLength = 10;

    void Start () {
        Shader shader = Shader.Find("Hidden/Internal-Colored");
        mat = CreateMaterial(shader, Color.white);
	}
    
    Material CreateMaterial(Shader s, Color c)
    {
        Material m = new Material(s);
        m.hideFlags = HideFlags.HideAndDontSave;
        // Turn on alpha blending
        m.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
        m.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
        // Turn backface culling off
        m.SetInt("_Cull", (int)UnityEngine.Rendering.CullMode.Off);
        // Turn off depth writes
        m.SetInt("_ZWrite", 0);
        m.SetColor("_Color", c);
        return m;
    }

    void OnPostRender()
    {
        Vector3 mousePos = Input.mousePosition;
        int width = ((int)mousePos.x - margin) / segmentLength;
        int height = ((int)mousePos.y - margin) / segmentLength;
        mat.SetPass(0);
        GL.PushMatrix();
        GL.LoadOrtho();
        GL.Begin(GL.LINES);
        x0 = y0 = 0;
        BiScan(width, height);
        GL.End();
        GL.PopMatrix();
    }

    void Update() {
        float scroll = Input.GetAxis("Mouse ScrollWheel");
        if(scroll < 0)
        {
            segmentLength -= 1;
            if (2 > segmentLength)
            {
                segmentLength = 2;
            }
        }
        else if(scroll > 0)
        {
            segmentLength += 1;
        }
    }

    void link(int a, int b)
    {
        //Debug.Log("(" + x0 + "," + y0 + ")");
        int x1 = x0 + a;
        int y1 = y0 + b;
        GL.Vertex3(xtrans(x0), ytrans(y0), 0f);
        GL.Vertex3(xtrans(x1), ytrans(y1), 0f);
        x0 = x1;
        y0 = y1;
    }

    float xtrans(int x)
    {
        return (float)(margin + x * segmentLength) / Screen.width; 
    }

    float ytrans(int y)
    {
        return (float)(margin + y * segmentLength) / Screen.height;
    }

    bool even(int x)
    {
        return(0 ==(x % 2));
    }

    void BiScan(int width, int height)
    {
        if (even(width) && even(height))
        {
            if (height > width)
            {
                Bic(height, width, 0, 1, 1, 0);
            }
            else
            {
                Bic(width, height, 1, 0, 0, 1);
            }
        }
        else
        {
            Bit(width, height, 1, 0, 0, 1);
        }
    }

    void Bic(int m, int n, int a, int b, int c, int d)
    {
	    int m1, m2;

        m1 = m2 = m / 2;
	    if(even(n) && even(m1))
        {
            m1 += 1;
            m2 -= 1;
        }
        Bit(m1, n, a, b, c, d);
        link(a, b);
        Bit(m2, n, a, b, - c, - d);
    }

    void Bit(int m, int n, int a, int b, int c, int d)
    {
	    int i;

        if (1 == m)
        {
            for (i = 1; i < n; i++)
            {
                link(c, d);
            }
        }
        else if (1 == n)
        {
            for (i = 1; i < m; i++)
            {
                link(a, b);
            }
        }
        else
        {
            int m1, m2;

            if (m < n)
            {
                swap(ref m, ref n);
                swap(ref a, ref c);
                swap(ref b, ref d);
            }
            m1 = m2 = m / 2;
            int m4 = m % 4;
            if(1 == m4)
            {
                m2 += 1;
            }
            else if(2 == m4)
            {
                m1 += 1;
                m2 -= 1;
            }
            else if(3 == m4)
            {
                m1 += 1;
            }
            Bic(m1, n, a, b, c, d);
            link(a, b);
            Bit(m2, n, a, b, c, d);
        }
    }

    void swap(ref int a, ref int b)
    {
        int t;
        t = a;
        a = b;
        b = t;
    }
}