参考资料:http://www.cnblogs.com/jeason1997/p/5130413.html

** 描述:雷达图

刷新 radarDate.SetVerticesDirty();

using UnityEngine;

using UnityEditor;

using UnityEngine.UI;





[AddComponentMenu("UI/Extensions/RadarEditor")]

public class RadarEditor : MaskableGraphic

{

    public bool isFill = true;

    [Range(0, 0.99f)]

    public float fillPercent = 0.8f;

    [Range(0f, 1f)]

    public float[] values;

    [Range(0f, 360f)]

    public float angleOffset = 0;

    public bool useStateLine = true;

    public Color lineColor = Color.white;

    public float lineWidth = 0.5f;

    [Range(0f, 1f)]

    public float lineLength = 0.8f;

    /// <summary>

    /// 重写OnPopulateMesh

    /// </summary>

    /// <param name="vh"></param>

    protected override void OnPopulateMesh(VertexHelper vh)

    {

        Vector2 size = GetComponent<RectTransform>().rect.size / 2f;

        vh.Clear();

        int partCount = values.Length;

        for (int i = 0; i < partCount; i++)

        {

            Vector2 pos1 = GetPoint(size, i) * values[i];

            Vector2 pos2 = isFill ? Vector2.zero : (pos1 * fillPercent);

            Vector2 pos4 = (i + 1 >= partCount) ? (GetPoint(size, 0) * values[0]) : (GetPoint(size, i + 1) * values[i + 1]);

            Vector2 pos3 = isFill ? Vector2.zero : (pos4 * fillPercent);

            vh.AddUIVertexQuad(GetQuad(pos1, pos2, pos3, pos4));

            if (useStateLine)

            {

                if (i != 0)

                {

                    Vector2 lineEndPos = GetPoint(size, i) * lineLength;

                    Vector2 lineStartPos = Vector2.zero;

                    vh.AddUIVertexQuad(GetLine(lineStartPos, lineEndPos));

                }

                if (i + 1 == partCount)

                {

                    Vector2 lineEndPos = GetPoint(size, 0) * lineLength;

                    Vector2 lineStartPos = Vector2.zero;

                    vh.AddUIVertexQuad(GetLine(lineStartPos, lineEndPos));

                }

            }

        }

    }

    /// <summary>

    /// 画线

    /// </summary>

    /// <param name="start"></param>

    /// <param name="end"></param>

    /// <returns></returns>

    private UIVertex[] GetLine(Vector2 start, Vector2 end)

    {

        UIVertex[] vs = new UIVertex[4];

        Vector2[] uv = new Vector2[4];

        uv[0] = new Vector2(0, 0);

        uv[1] = new Vector2(0, 1);

        uv[2] = new Vector2(1, 0);

        uv[3] = new Vector2(1, 1);

        Vector2 v1 = end - start;

        Vector2 v2 = (v1.y == 0f) ? new Vector2(0f, 1f) : new Vector2(1f, -v1.x / v1.y);

        v2.Normalize();

        v2 *= lineWidth / 2f;

        Vector2[] pos = new Vector2[4];

        pos[0] = start + v2;

        pos[1] = end + v2;

        pos[2] = end - v2;

        pos[3] = start - v2;

        for (int i = 0; i < 4; i++)

        {

            UIVertex v = UIVertex.simpleVert;

            v.color = lineColor;

            v.position = pos[i];

            v.uv0 = uv[i];

            vs[i] = v;

        }

        return vs;

    }

    /// <summary>

    /// 获取点Vector2

    /// </summary>

    /// <param name="size"></param>

    /// <param name="i"></param>

    /// <returns></returns>

    private Vector2 GetPoint(Vector2 size, int i)

    {

        int partCount = values.Length;

        float angle = 360f / partCount * i + angleOffset;

        float sin = Mathf.Sin(angle * Mathf.Deg2Rad);

        float cos = Mathf.Cos(angle * Mathf.Deg2Rad);

        return new Vector2(size.x * cos, size.y * sin);

    }





    /// <summary>

    /// 根据点获取UIVertex

    /// </summary>

    /// <param name="vertPos"></param>

    /// <returns></returns>

    private UIVertex[] GetQuad(params Vector2[] vertPos)

    {

        UIVertex[] vs = new UIVertex[4];

        Vector2[] uv = new Vector2[4];

        uv[0] = new Vector2(0, 0);

        uv[1] = new Vector2(0, 1);

        uv[2] = new Vector2(1, 0);

        uv[3] = new Vector2(1, 1);

        for (int i = 0; i < 4; i++)

        {

            UIVertex v = UIVertex.simpleVert;

            v.color = color;

            v.position = vertPos[i];

            v.uv0 = uv[i];

            vs[i] = v;

        }

        return vs;

    }

}

Unity里的Mesh属性

Mesh是Unity内的一个组件,称为网格组件。

Mesh:是指模型的网格,建模就是建网格。细看Mesh,可以知道Mesh的主要属性内容包括顶点坐标,法线,纹理坐标,三角形绘制序列等其他有用属性和功能。因此建网格,就是画三角形;画三角形就是定位三个点。

Mesh Filter:内包含一个Mesh组件,可以根据MeshFilter获得模型网格的组件,也可以为MeshFilter设置Mesh内容。

Mesh Render:是用于把网格渲染出来的组件。MeshFilter的作用就是把Mesh扔给MeshRender将模型或者说是几何体绘制显示出来。

它们之间的关系大概就是Unity中的对象就是GameObject,每个GameObject都可以有一个MeshFilter组件(也可以没有),该组件又有Mesh属性(这个一定有),而该属性又有顶点坐标,法线等属性。而如果GameObject里有MeshFilter,则必须要Mesh Renderer才能将此网格渲染出来,不然是看不见该网格的。

 

Mesh的属性:

  • 顶点坐标(vertex)
  • 法线(normal)
  • 纹理坐标(uv)
  • 三角形序列(triangle)

顶点坐标:顶点坐标数组存放Mesh的每个顶点的空间坐标,假设某mesh有n个顶点,则vertex的size为n

法线:法线数组存放mesh每个顶点的法线,大小与顶点坐标对应,normal[i]对应顶点vertex[i]的法线

纹理坐标:它定义了图片上每个点的位置的信息. 这些点与3D模型是相互联系的, 以决定表面纹理贴图的位置. UV就是将图像上每一个点精确对应到模型物体的表面.
uv[i]对应vertex[i]

三角形序列:每个mesh都由若干个三角形组成,而三角形的三个点就是顶点坐标里的点,三角形的数组的size = 三角形个数 * 3.

例如:某mesh有四个顶点0,1,2,3,

V0(1, 1, 0),

V1(-1, 1, 0),

V2(1, -1, 0),

V3(-1, -1, 0)

那么它们可以组成这样的一个网格,

tri[0] = ver[0],ver[3],ver[1],tri[1] = ver[0],ver[2],ver[3],

注意:三角形的顶点顺序必须是顺时针,顺时针表示正面,逆时针表示背面,而unity3d在渲染时默认只渲染正面,背面是看不见的。

那么该三角形可以表示为:

tri  = new int[2 * 3]{0, 3, 1,   0, 2, 3};

如何要获取第N个三角形对应的三个顶点坐标,则:v1 = tri[N*3 + 0], v2 = tri[N*3 + 1], v3 = tir[N*3 + 2]

示例:

1.创建一个GameObject并添加MeshFilter以及MeshRender组件,并创建一个“CreateMesh.cs”脚本给它。

2.获取该对象的filter组件,并创建一个mesh给它。

3.为该mesh设置属性,这里先设置顶点,然后将三角形与顶点绑定

 1 using UnityEngine;
 2 using System.Collections;
 3
 4 public class CreateMesh : MonoBehaviour {
 5
 6     private MeshFilter filter;
 7     private Mesh mesh;
 8
 9     // Use this for initialization
10     void Start () {
11         // 获取GameObject的Filter组件
12         filter = GetComponent<MeshFilter>();
13         // 并新建一个mesh给它
14         mesh = new Mesh();
15         filter.mesh = mesh;
16
17         // 初始化网格
18         InitMesh();
19     }
20
21     // Update is called once per frame
22     void Update () {
23
24     }
25
26     /// <summary>
27     /// Inits the mesh.
28     /// </summary>
29     void InitMesh()
30     {
31         mesh.name = "MyMesh";
32
33         // 为网格创建顶点数组
34         Vector3[] vertices = new Vector3[4]{
35             new Vector3(1, 1, 0),
36             new Vector3(-1, 1, 0),
37             new Vector3(1, -1, 0),
38             new Vector3(-1, -1, 0)
39         };
40
41         mesh.vertices = vertices;
42
43         // 通过顶点为网格创建三角形
44         int[] triangles = new int[2 * 3]{
45             0, 3, 1,   0, 2, 3
46         };
47
48         mesh.triangles = triangles;
49     }
50 }

效果如图:

3.网格已经成功生成,接下来该给网格贴图了,在Inspector视图里选中Mesh Render,并拖一个材质给它,

Mesh Render是负责渲染的,将Mesh Filter里的mesh通过自身的Materials渲染出来。

设置完材质后,我们需要将纹理贴图与网格顶点一一对应起来,这样才能渲染出来。

// 为mesh设置纹理贴图坐标
        Vector2[] uv = new Vector2[4]{
            new Vector2(1, 1),
            new Vector2(0, 1),
            new Vector2(1, 0),
            new Vector2(0, 0)
        };

        mesh.uv = uv;

效果如图:

4.mesh还有两个重要的属性,法线和颜色,这两个我不是很懂,暂时没加入,

不过看了下自带的cube模型的mesh,每个顶点的法线好像就是设置为那个顶点所在的面的法线。

不过肯定不是这样的,毕竟要是两个不在同一面的面共有一个顶点,那就不成立了。

Mesh绘制雷达图(UGUI)的更多相关文章

  1. 【带着canvas去流浪(6)】绘制雷达图

    目录 一. 任务说明 二. 重点提示 三. 示例代码 示例代码托管在:http://www.github.com/dashnowords/blogs 博客园地址:<大史住在大前端>原创博文 ...

  2. Emgu-WPF 激光雷达研究-绘制雷达图

    原文:Emgu-WPF 激光雷达研究-绘制雷达图 硬件:Hokuyo URG04LX 环境:VS2017- win10- 64  Emgu_3.2.0.2682 语言:C#  WPF   数据解析参考 ...

  3. 带着canvas去流浪系列之六 绘制雷达图

    [摘要] 用canvas原生API实现百度Echarts基本图表. 示例代码托管在:http://www.github.com/dashnowords/blogs 一. 任务说明 使用原生canvas ...

  4. 利用matlibplot绘制雷达图

    之前在一些数据分析案例中看到用 Go 语言绘制的雷达图,非常的漂亮,就想着用matlibplot.pyplot也照着画一个,遗憾的是matlibplot.pyplot模块中没有直接绘制雷达图的函数,不 ...

  5. 利用d3.js绘制雷达图

    利用d3,js将数据可视化,能够做到数据与代码的分离.方便以后改动数据. 这次利用d3.js绘制了一个五维的雷达图.即将多个对象的五种属性在一张图上对照. 数据写入data.csv.数据类型写入typ ...

  6. C# 使用GDI绘制雷达图

    最近项目要用C#实现画一个雷达图,搜了搜网上竟然找不到C#画雷达图的解决方案,那么自己实现一个吧 实现效果如下图: 代码如下: public static class RadarDemo { ; ; ...

  7. Python绘制雷达图(俗称六芒星)

    原文链接:https://blog.csdn.net/Just_youHG/article/details/83904618 背景 <Python数据分析与挖掘实战> 案例2–航空公司客户 ...

  8. wepy绘制雷达图

    代码如下: <style lang='less'> .radar-canvas2 { width: 690rpx; height: 420rpx; } </style> < ...

  9. R语言绘图:雷达图

    使用fmsb包绘制雷达图 library("fmsb") radarfig <- rbind(rep(90, 4), rep(60, 4), c(86.17, 73.96, ...

随机推荐

  1. 关于连不上dc服务器的机器强行退出域的方法

    有时加入域的计算机无法连接到之前的域了,只能强制退出域了,有两个前提条件:   1.断开网络,就是拔掉网线或者禁用网卡.   2.使用本地管理员登陆.   然后命令行执行如下命令即可:   netdo ...

  2. validate方法配置项

    validate()方法配置项 submitHandler 通过验证后运行的函数,可以加上表单提交的方法 invalidHandler 无效表单提交后运行的函数 ignore 对某些元素不进行验证 r ...

  3. 全球最低功耗蓝牙单芯片(DA14580)系统架构和应用开发框架分析

    DA14580是Dialog公司研制的蓝牙单芯片,号称全球功耗最低,是TI CC2541的四分之一,是运动手环等穿戴类电子产品的常用芯片.但是DA14580的开发门槛不低,适合有蓝牙开发经验的团队来开 ...

  4. 在 Java 中高效使用锁的技巧--转载

    竞争锁是造成多线程应用程序性能瓶颈的主要原因 区分竞争锁和非竞争锁对性能的影响非常重要.如果一个锁自始至终只被一个线程使用,那么 JVM 有能力优化它带来的绝大部分损耗.如果一个锁被多个线程使用过,但 ...

  5. Fedora14下首次搭建Samba服务器遇到的一些问题

    SMB(Server Messages Block,信息服务块)是一种在局域网上共享文件和打印机的通信协议.而Samba则是在Linux和Unix系统上实现SMB协议的一个免费软件,由服务器及客户端程 ...

  6. [转] Linux文件系统之hard link&symbol link

    这个图很清楚的表示出硬链接和软链接的方式. 1.硬链接: 基本定义:硬链接是有着相同inode号的仅文件名不同的文件(该文件名包含路径信息). 理解:如图,hard link和原始file通过同一个i ...

  7. nmap使用方法

      你是否曾想知道你所在局域网中哪些IP已经被使用了?还有哪些IP地址没有被使用?是否想知道某个IP地址下是什么系统…… 这些问题我们都可以使用一个nmap的工具解决,下面,就让我们开始了解nmap. ...

  8. 线程技术 ☞ Future模式

    线程技术可以让我们的程序同时做多件事情,线程的工作模式有很多,常见的一种模式就是处理网站的并发,今天我来说说线程另一种很常见的模式,这个模式和前端里的ajax类似:浏览器一个主线程执行javascri ...

  9. DataSet离线数据集实例

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.W ...

  10. VB指针 与CopyMemory

    体会ByVal和ByRef Dim k As Long CopyMemory ByVal VarPtr(k), 40000, 4 等同于k=40000:从保存常数40000(缺省ByRef)的临时变量 ...