ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Unity制作3D图表组件------扇形图

2020-06-03 18:55:02  阅读:308  来源: 互联网

标签:float Vector3 Unity points outPutPoints 组件 new size 3D


上篇有柱状图于折线图的实现。

这篇主要实现一下柱状图。

实现方式:把圆环体拆分成一个一个的小长方体,如图(顶视图)绿色部分

 

还是继承ChartBase.cs

上代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// 扇形统计图
/// </summary>
public class SectorChart : ChartBase
{
    List<float> tempPointY = new List<float>();
    /// <summary>
    /// 展示动画
    /// </summary>
    public override void ShowAnim()
    {
        for (int i = 0; i < pointsInfos.Count; i++)
        {
            for (int j = 0; j < pointsInfos[i].itemSectorPercent.Length; j++)
            {
                int tempI = i;
                int tempJ = j;

                StartCoroutine(DoFloatValue(0, pointsInfos[i].itemSectorPercent[j], 1, (value) =>
                {
                    pointsInfos[tempI].itemSectorPercent[tempJ] = value;
                }));
            }
        }
    }


    public override void CreateMesh()
    {

        for (int i = 0; i < pointsInfos.Count; i++)
        {
            if (pointsInfos[i].itemSectorPercent.Length != meshs.Count)
            {
                DeleteAllItemObjs();
                GameObject tempParent = new GameObject();
                tempParent.name = meshName;
                tempParent.transform.position = Vector3.zero;
                allChartParentObj.Add(tempParent);
                for (int j = 0; j < pointsInfos[i].itemSectorPercent.Length; j++)
                {
                    GameObject itemObj = new GameObject();
                    itemObj.name = meshName + "_Child_" + j.ToString();
                    itemObj.transform.parent = tempParent.transform;
                    Mesh mesh = new Mesh();
                    meshs.Add(mesh);
                    itemObj.AddComponent<MeshFilter>().mesh = mesh;
                    itemObj.AddComponent<MeshRenderer>();
                    itemObj.GetComponent<MeshRenderer>().material = mat;
                    allChartItemObj.Add(itemObj);
                }
            }
        }
    }
    /// <summary>
    /// 当前这个扇形的起始角度
    /// </summary>
    float pieceAngle = 0;
    /// <summary>
    /// 当前这个扇形的结束角度
    /// </summary>
    float nextAngle = 0;

    public override void SetMeshInfo()
    {
        triangles.Clear();
        verticesAddOffset.Clear();

        pieceAngle = 0;
        nextAngle = 0;

        for (int j = 0; j < pointsInfos[0].itemSectorPercent.Length; j++)
        {
            Vector3[] vertices = GetPointsVector3s(pointsInfos[0], j);
            verticesAddOffset.Add(new PointsInfo(SetVerticesOffset(vertices, pointsInfos[0]), Vector3.one));
            triangles.Add(GetTrianglesVector3s(vertices));
        }
    }


    /// <summary>
    /// 根据顶点和位移差获取最终位置
    /// </summary>
    /// <param name="vertices"></param>
    /// <param name="index"></param>
    /// <returns></returns>
    public override Vector3[] SetVerticesOffset(Vector3[] vertices, PointsInfo _points)
    {

        Vector3[] tempV3 = new Vector3[vertices.Length];

        for (int i = 0; i < vertices.Length; i++)
        {
            tempV3[i] = vertices[i];

            tempV3[i] += _points.points[0];

        }

        return tempV3;
    }


    /// <summary>
    /// 获取正方体的每个面顶点坐标   (先绘出顶面第一个长方形,再绘制底面第一个长方形,依次连接长方体的面)
    /// </summary>
    /// <param name="count"></param>
    /// <returns></returns>
    protected Vector3[] GetPointsVector3s(PointsInfo _points, int index)
    {

        List<Vector3> tempPoints = new List<Vector3>();

        //立方体初始的点,取内圆心   上表面的一个点
        Vector3 firstUpPoint = new Vector3(_points.size.x * _points.inCirclePercent, -_points.size.y / 2f, 0);
        ///上表面的中心点
        Vector3 centerUp = center + new Vector3(0, _points.size.y / 2f, 0);

        if (index == 0)
        {
            pieceAngle = 0;
        }
        else
        {
            pieceAngle += _points.itemSectorPercent[index - 1] * 360f;
        }

        nextAngle += _points.itemSectorPercent[index] * 360f;
        float offsetAngle = nextAngle - pieceAngle;
        for (int i = 0; i < _points.sertorCount; i++)
        {
            //立方体上表面多边形点
            List<Vector3> tempUpPoints = new List<Vector3>();
            //立方体下表面多边形点
            List<Vector3> tempDownPoints = new List<Vector3>();

            float tempAngle = pieceAngle + (float)(i) / (float)_points.sertorCount * (nextAngle - pieceAngle);
            float tempNextAngle = pieceAngle + (float)(i + 1) / (float)_points.sertorCount * (nextAngle - pieceAngle);
            if (i == 0)
            {
                tempUpPoints.Add(RotateAroundByPointByDistance(firstUpPoint, centerUp, Vector3.up, _points.size.x * _points.inCirclePercent, tempAngle, offsetAngle * _points.insertValue));
                tempUpPoints.Add(RotateAroundByPointByDistance(firstUpPoint, centerUp, Vector3.up, _points.size.x, tempAngle, offsetAngle * _points.insertValue));
            }
            else
            {
                tempUpPoints.Add(RotateAroundByPointByDistance(firstUpPoint, centerUp, Vector3.up, _points.size.x * _points.inCirclePercent, tempAngle));
                tempUpPoints.Add(RotateAroundByPointByDistance(firstUpPoint, centerUp, Vector3.up, _points.size.x, tempAngle));
            }
            if (i == _points.sertorCount - 1)
            {
                tempUpPoints.Add(RotateAroundByPointByDistance(firstUpPoint, centerUp, Vector3.up, _points.size.x, tempNextAngle, -offsetAngle * _points.insertValue));
                tempUpPoints.Add(RotateAroundByPointByDistance(firstUpPoint, centerUp, Vector3.up, _points.size.x * _points.inCirclePercent, tempNextAngle, -offsetAngle * _points.insertValue));
            }
            else
            {
                tempUpPoints.Add(RotateAroundByPointByDistance(firstUpPoint, centerUp, Vector3.up, _points.size.x, tempNextAngle));
                tempUpPoints.Add(RotateAroundByPointByDistance(firstUpPoint, centerUp, Vector3.up, _points.size.x * _points.inCirclePercent, tempNextAngle));
            }


            for (int j = 0; j < tempUpPoints.Count; j++)
            {
                tempDownPoints.Add(tempUpPoints[j] - new Vector3(0, _points.size.y, 0));
            }
            tempPoints.AddRange(GetAllTrianglesPoint(tempUpPoints, tempDownPoints));

        }

        return tempPoints.ToArray();
    }
    /// <summary>
    /// 根据上表面下表面的八个顶点确定立方体的所有点位(顺时针排序)
    /// </summary>
    /// <param name="inputUpV3s">上表面的四个点</param>
    /// <param name="inputDownV3s">下表面的四个点</param>
    /// <returns></returns>
    Vector3[] GetAllTrianglesPoint(List<Vector3> inputUpV3s, List<Vector3> inputDownV3s, string ceMian = "Both")
    {
        Vector3[] outPutPoints = new Vector3[24];

        //顶面
        for (int i = 0; i < inputUpV3s.Count; i++)
        {
            outPutPoints[i] = inputUpV3s[i];
        }
        //内侧
        outPutPoints[4] = inputUpV3s[0];
        outPutPoints[5] = inputUpV3s[3];
        outPutPoints[6] = inputDownV3s[3];
        outPutPoints[7] = inputDownV3s[0];

        //右面
        if (ceMian == "Both" || ceMian == "Right")
        {
            outPutPoints[8] = inputUpV3s[3];
            outPutPoints[9] = inputUpV3s[2];
            outPutPoints[10] = inputDownV3s[2];
            outPutPoints[11] = inputDownV3s[3];
        }
        //外侧
        outPutPoints[12] = inputUpV3s[2];
        outPutPoints[13] = inputUpV3s[1];
        outPutPoints[14] = inputDownV3s[1];
        outPutPoints[15] = inputDownV3s[2];

        //左面
        if (ceMian == "Both" || ceMian == "Left")
        {
            outPutPoints[16] = inputUpV3s[1];
            outPutPoints[17] = inputUpV3s[0];
            outPutPoints[18] = inputDownV3s[0];
            outPutPoints[19] = inputDownV3s[1];
        }

        //底面
        outPutPoints[20] = inputDownV3s[3];
        outPutPoints[21] = inputDownV3s[2];
        outPutPoints[22] = inputDownV3s[1];
        outPutPoints[23] = inputDownV3s[0];

        return outPutPoints;
    }


    public Vector3 RotateAroundByPointByDistance(Vector3 selfPoint, Vector3 rotatePoint, Vector3 axis, float distance, float angle, float offsetAngle = 0)
    {
        Quaternion q = Quaternion.AngleAxis(angle + offsetAngle, axis);
        Vector3 distanceOffset = Vector3.ProjectOnPlane(Vector3.Normalize(new Vector3((1 - axis.x) * selfPoint.x, (1 - axis.y) * selfPoint.y, (1 - axis.z) * selfPoint.z) - new Vector3((1 - axis.x) * rotatePoint.x, (1 - axis.y) * rotatePoint.y, (1 - axis.z) * rotatePoint.z)), axis) * distance;
        return q * distanceOffset;
    }

}



public partial class PointsInfo
{
    /// <summary>
    /// 内圈比例
    /// </summary>
    public float inCirclePercent;
    /// <summary>
    /// 扇形之间的间隔
    /// </summary>
    public float insertValue;
    /// <summary>
    /// 多边形边数
    /// </summary>
    public int sertorCount;

    /// <summary>
    /// 每个扇形的百分比
    /// </summary>
    public float[] itemSectorPercent;
    public PointsInfo(Vector3[] _points, Vector3 _size, float _percent, float _insertValue, int _sertorCount, float[] _itemSectorPercent)
    {
        points = _points;
        size = _size;
        inCirclePercent = _percent;
        insertValue = _insertValue;
        sertorCount = _sertorCount;
        itemSectorPercent = _itemSectorPercent;
    }
}

 

标签:float,Vector3,Unity,points,outPutPoints,组件,new,size,3D
来源: https://www.cnblogs.com/yzxhz/p/13039362.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有