unity 饼状图

using UnityEngine;


public class PieChartMesh : MonoBehaviour
{
    float[] mData;
    int mSlices;
    float mRotationAngle;
    float mRadius;


    Vector3[] mVertices;
    Vector3[] mNormals;
    Vector3 mNormal = new Vector3(0f, 0f, -1f);
    Vector2[] mUvs;
    int[] mTriangles;


    MeshRenderer mMeshRenderer;


    public void Init(float[] data, int slices, float rotatioAngle, float radius)
    {
        mData = data;
        mSlices = slices;
        mRotationAngle = rotatioAngle;
        mRadius = radius;


        // Get Mesh Renderer
        mMeshRenderer = gameObject.GetComponent("MeshRenderer") as MeshRenderer;
        if (mMeshRenderer == null)
        {
            gameObject.AddComponent("MeshRenderer");
            mMeshRenderer = gameObject.GetComponent("MeshRenderer") as MeshRenderer;
        }
    }


    public void Draw(float[] data)
    {
        mData = data;
        Draw();
    }


    public void Draw()
    {


        //Check data validity for pie chart...
        if (mData == null)
        {
            print("PieChart: Data null");
            return;
        }


        // Calculate sum of data values
        float sumOfData = 0;
        foreach (float value in mData)
        {
            sumOfData += value;
        }


        // Determine how many triangles in slice
        int[] slice = new int[mData.Length];
        int numOfTris = 0;
        int numOfSlices = 0;
        int countedSlices = 0;


        // Caluclate slice size 
        for (int i = 0; i < mData.Length; i++)
        {
            numOfTris = (int)((mData[i] / sumOfData) * mSlices);
            slice[numOfSlices++] = numOfTris;
            countedSlices += numOfTris;
        }
        // Check that all slices are counted.. if not -> add/sub to/from biggest slice..
        int idxOfLargestSlice = 0;
        int largestSliceCount = 0;
        for (int i = 0; i < mData.Length; i++)
        {
            if (largestSliceCount < slice[i])
            {
                idxOfLargestSlice = i;
                largestSliceCount = slice[i];
            }
        }


        // Adjust largest dataset to get proper slice 
        slice[idxOfLargestSlice] += mSlices - countedSlices;


        // Init vertices and triangles arrays
        mVertices = new Vector3[mSlices * 3];
        mNormals = new Vector3[mSlices * 3];
        mUvs = new Vector2[mSlices * 3];
        mTriangles = new int[mSlices * 3];




        Mesh mesh = ((MeshFilter)GetComponent("MeshFilter")).mesh;


        mesh.Clear();


        mesh.name = "Pie Chart Mesh";


        // Roration offset (to get star point to "12 o'clock")
        float rotOffset = mRotationAngle / 360f * 2f * Mathf.PI;


        // Calc the points in circle
        float angle;
        float[] x = new float[mSlices];
        float[] y = new float[mSlices];


        for (int i = 0; i < mSlices; i++)
        {
            angle = i * 2f * Mathf.PI / mSlices;
            x[i] = (Mathf.Cos(angle + rotOffset) * mRadius);
            y[i] = (Mathf.Sin(angle + rotOffset) * mRadius);
        }


        // Generate mesh with slices (vertices and triangles)
        for (int i = 0; i < mSlices; i++)
        {
            mVertices[i * 3 + 0] = new Vector3(0f, 0f, 0f);
            mVertices[i * 3 + 1] = new Vector3(x[i], y[i], 0f);
            // This will ensure that last vertex = first vertex..
            mVertices[i * 3 + 2] = new Vector3(x[(i + 1) % mSlices], y[(i + 1) % mSlices], 0f);


            mNormals[i * 3 + 0] = mNormal;
            mNormals[i * 3 + 1] = mNormal;
            mNormals[i * 3 + 2] = mNormal;


            mUvs[i * 3 + 0] = new Vector2(0f, 0f);
            mUvs[i * 3 + 1] = new Vector2(x[i], y[i]);
            // This will ensure that last uv = first uv..
            mUvs[i * 3 + 2] = new Vector2(x[(i + 1) % mSlices], y[(i + 1) % mSlices]);


            mTriangles[i * 3 + 0] = i * 3 + 0;
            mTriangles[i * 3 + 1] = i * 3 + 1;
            mTriangles[i * 3 + 2] = i * 3 + 2;
        }




        // Assign verts, norms, uvs and tris to mesh and calc normals
        mesh.vertices = mVertices;
        mesh.normals = mNormals;
        mesh.uv = mUvs;
        //mesh.triangles = triangles;


        mesh.subMeshCount = mData.Length;


        int[][] subTris = new int[mData.Length][];


        countedSlices = 0;


        // Set sub meshes
        for (int i = 0; i < mData.Length; i++)
        {
            // Every triangle has three veritces..
            subTris[i] = new int[slice[i] * 3];


            // Add tris to subTris
            for (int j = 0; j < slice[i]; j++)
            {
                subTris[i][j * 3 + 0] = mTriangles[countedSlices * 3 + 0];
                subTris[i][j * 3 + 1] = mTriangles[countedSlices * 3 + 1];
                subTris[i][j * 3 + 2] = mTriangles[countedSlices * 3 + 2];


                countedSlices++;
            }
            mesh.SetTriangles(subTris[i], i);
        }
    }

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值