Mesh绘制雷达图(UGUI)
参考资料: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 网格
- MeshFilter 网格过滤器
- Mesh Renderer 网格渲染器
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)的更多相关文章
- 【带着canvas去流浪(6)】绘制雷达图
目录 一. 任务说明 二. 重点提示 三. 示例代码 示例代码托管在:http://www.github.com/dashnowords/blogs 博客园地址:<大史住在大前端>原创博文 ...
- Emgu-WPF 激光雷达研究-绘制雷达图
原文:Emgu-WPF 激光雷达研究-绘制雷达图 硬件:Hokuyo URG04LX 环境:VS2017- win10- 64 Emgu_3.2.0.2682 语言:C# WPF 数据解析参考 ...
- 带着canvas去流浪系列之六 绘制雷达图
[摘要] 用canvas原生API实现百度Echarts基本图表. 示例代码托管在:http://www.github.com/dashnowords/blogs 一. 任务说明 使用原生canvas ...
- 利用matlibplot绘制雷达图
之前在一些数据分析案例中看到用 Go 语言绘制的雷达图,非常的漂亮,就想着用matlibplot.pyplot也照着画一个,遗憾的是matlibplot.pyplot模块中没有直接绘制雷达图的函数,不 ...
- 利用d3.js绘制雷达图
利用d3,js将数据可视化,能够做到数据与代码的分离.方便以后改动数据. 这次利用d3.js绘制了一个五维的雷达图.即将多个对象的五种属性在一张图上对照. 数据写入data.csv.数据类型写入typ ...
- C# 使用GDI绘制雷达图
最近项目要用C#实现画一个雷达图,搜了搜网上竟然找不到C#画雷达图的解决方案,那么自己实现一个吧 实现效果如下图: 代码如下: public static class RadarDemo { ; ; ...
- Python绘制雷达图(俗称六芒星)
原文链接:https://blog.csdn.net/Just_youHG/article/details/83904618 背景 <Python数据分析与挖掘实战> 案例2–航空公司客户 ...
- wepy绘制雷达图
代码如下: <style lang='less'> .radar-canvas2 { width: 690rpx; height: 420rpx; } </style> < ...
- R语言绘图:雷达图
使用fmsb包绘制雷达图 library("fmsb") radarfig <- rbind(rep(90, 4), rep(60, 4), c(86.17, 73.96, ...
随机推荐
- IT项目经理应具备的十大软技能
现在,企业对IT部项目经理的要求越来越多.如果你认为IT项目成员只需要技术性能力,那可就错了. 据IT招聘公司调查发现,几年人们对项目管理软技能的兴趣明显浓厚起来.许多企业尽量避免把IT部门看成只是成 ...
- boost库在工作(32)网络服务端之二
在这个例子里,服务器对象主要使用boost::asio::io_service对象,这个对象主要用来构造异步接收数据使用,接着定义boost::asio::ip::tcp::acceptor对象,这个 ...
- Sublime 注册码
----- BEGIN LICENSE ----- Andrew Weber Single User License EA7E-855605 813A03DD 5E4AD9E6 6C0EEB94 BC ...
- 字体图标 icon font
Icon font icon font 指的是用字体文件代替图片文件,来展示图标.特殊字体等元素的方法. 应用场景: iconfont的优缺点 大小能够自由地变化 颜色能够自由地改动 加入阴影效果 * ...
- eclipse设置系统字体
1. 打开eclipse-->Window-->Preferences-->General-->appearance-->Colors and Fonts, 点开后选择B ...
- Android - 软件自动更新的实现(转)
在客户端实现更新操作 涉及到三个技术: 1.xml文件的解析 2.HttpURLConnection连接 3.文件流I/O 这里创建一个解析xml文件的服务类:ParXmlService.java p ...
- python 全栈开发之路 day1
python 全栈开发之路 day1 本节内容 计算机发展介绍 计算机硬件组成 计算机基本原理 计算机 计算机(computer)俗称电脑,是一种用于高速计算的电子计算机器,可以进行数值计算,又可 ...
- 教学项目之-通过Python实现简单的计算器
教学项目之-通过Python实现简单的计算器 计算器开发需求 实现加减乘除及拓号优先级解析 用户输入 1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/ ...
- 转载:C# HashSet 用法
原文地址:http://www.cnblogs.com/xiaopin/archive/2011/01/08/1930540.html 感谢博主分享! NET 3.5在System.Collect ...
- 13、SQL Server 自定义函数
SQL Server 自定义函数 在SQL Server中不仅可以使用系统函数(如:聚合函数,字符串函数,时间日期函数等)还可以根据需要自定义函数. 自定义函数分为标量值函数和表值函数. 其中,标量值 ...