AutoCAD 3DMAX C语言 Pro/E UG JAVA编程 PHP编程 Maya动画 Matlab应用 Android
Photoshop Word Excel flash VB编程 VC编程 Coreldraw SolidWorks A Designer Unity3D
 首页 > Unity3D

【Unity C#编程】图表 可视化数据:3D展示

51自学网 2014-05-24 http://www.51zixue.net

本文由Aoi翻译,转载请注明出处。文章来自于catlikecoding,原文作者介绍了Unity制作图表、可视化数据的方法。文章最后提供完成文件下载,更多的名词解释内容,请点击末尾的“原文链接”查看。


 

完全成熟的 3D

现在该添加第三个维度了!这将让图表从网格进化成立方体,可以用体积来表示。换句话说,我们将创建一个小小的三维像素系统。

复制Graph 2Grapher2 ,然后改成 Graph 3Grapher3, 就像做第二图表那样。不要忘了禁用Graph 2 ,并且确保不再播放模式。


 

 

三个图表对象

Grapher3做些修改。首先,把分辨率限制为30,转换为27000个点。确保你调整的是分辨率滑块,那样就不会超过范围。如果你从复制品创建的,设置成更高的分辨率,它还是这个值。

我们还得初始化Y轴上的点以及绿色分量。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[Range(10, 30)]
public int resolution = 10;
 
private void CreatePoints () {
currentResolution = resolution;
points = new ParticleSystem.Particle[resolution * resolution * resolution];
float increment = 1f / (resolution - 1);
int i = 0;
for (int x = 0; x < resolution; x++) {
for (int z = 0; z < resolution; z++) {
for (int y = 0; y < resolution; y++) {
Vector3 p = new Vector3(x, y, z) * increment;
points[i].position = p;
points[i].color = new Color(p.x, p.y, p.z);
points[i++].size = 0.1f;
}
}
}
}

现在Graph 3 Graph 2看起来一样了,但是它看起来更牢靠。这是因为我们仍然在Update函数里设置Y轴。所以所有XZ都是一样的点将会有相同的Y轴位置。我们必须不再设置Y轴,而是以颜色的alpha分量来替代。那样函数就能定义体积的密度。

1
2
3
4
5
6
7
8
9
10
11
12
13
void Update () {
if (currentResolution != resolution || points == null) {
CreatePoints();
}
FunctionDelegate f = functionDelegates[(int)function];
float t = Time.timeSinceLevelLoad;
for (int i = 0; i < points.Length; i++) {
Color c = points[i].color;
c.a = f(points[i].position, t);
points[i].color = c;
}
particleSystem.SetParticles(points, points.Length);
}

分辨率为1030的立方体

现在,图表看起来更像一个坚固的立方体。该函数不是很明显,因为它们不是沿着Y轴变化的。只有两个动画函数,正弦和波纹,会产生一些有趣的结果。

让我们改变线性计算的函数f(x,y,z) = 1 - x - y – z这样它就从(0, 0, 0)开始,沿直线逐渐趋于透明。我们也可以用幂数做相似的东西。更妙的是,给它加点动画会变得更有趣!

1
2
3
4
5
6
7
private static float Linear (Vector3 p, float t) {
return 1f - p.x - p.y - p.z + 0.5f * Mathf.Sin(t);
}
 
private static float Exponential (Vector3 p, float t) {
return 1f - p.x * p.x - p.y * p.y - p.z * p.z + 0.5f * Mathf.Sin(t);
}

线性和幂数

接下来,更新 Parabola,这样就能产生一个圆柱体,再加一个小小的脉冲动画。也给波纹添加第三个维度,变成球形动画。

1
2
3
4
5
6
7
8
9
10
11
12
13
private static float Parabola (Vector3 p, float t){
p.x += p.x - 1f;
p.z += p.z - 1f;
return 1f - p.x * p.x - p.z * p.z + 0.5f * Mathf.Sin(t);
}
 
private static float Ripple (Vector3 p, float t){
p.x -= 0.5f;
p.y -= 0.5f;
p.z -= 0.5f;
float squareRadius = p.x * p.x + p.y * p.y + p.z * p.z;
return Mathf.Sin(4f * Mathf.PI * squareRadius - 2f * t);
}

抛物线和波纹

最后,更新正弦函数。把正弦的XYZ乘以平方,使其转变为8个斑点。我们只动画基于Z轴的正弦,在这里做一个区别,
 

1
2
3
4
5
6
private static float Sine (Vector3 p, float t){
float x = Mathf.Sin(2 * Mathf.PI * p.x);
float y = Mathf.Sin(2 * Mathf.PI * p.y);
float z = Mathf.Sin(2 * Mathf.PI * p.z + (p.y > 0.5f ? t : -t));
return x * x * y * y * z * z;
}

变形的正弦产生行进的斑点

图形变化的可圈可点之处是所有的体素都是可见的,或者是完全透明的。这将形成实心但是像素透明的物体。添加一个asbolute字段来切换这样的行为,同时有个阈值字段决定可见之前固化像素。每次更新检查asbolute是否开启,使用它来决定如何设置点的alpha。这是完整的脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
using UnityEngine;
 
public class Grapher3 : MonoBehaviour {
 
public enum FunctionOption {
Linear,
Exponential,
Parabola,
Sine,
Ripple
}
 
private delegate float FunctionDelegate (Vector3 p, float t);
private static FunctionDelegate[] functionDelegates = {
Linear,
Exponential,
Parabola,
Sine,
Ripple
};
 
public FunctionOption function;
public bool absolute;
public float threshold = 0.5f;
 
[Range(10, 30)]
public int resolution = 10;
 
private int currentResolution;
private ParticleSystem.Particle[] points;
 
private void CreatePoints () {
currentResolution = resolution;
points = new ParticleSystem.Particle[resolution * resolution * resolution];
float increment = 1f / (resolution - 1);
int i = 0;
for (int x = 0; x < resolution; x++) {
for (int z = 0; z < resolution; z++) {
for (int y = 0; y < resolution; y++) {
Vector3 p = new Vector3(x, y, z) * increment;
points[i].position = p;
points[i].color = new Color(p.x, p.y, p.z);
points[i++].size = 0.1f;
}
}
}
}
 
void Update () {
if (currentResolution != resolution || points == null) {
CreatePoints();
}
FunctionDelegate f = functionDelegates[(int)function];
float t = Time.timeSinceLevelLoad;
if (absolute) {
for (int i = 0; i < points.Length; i++) {
Color c = points[i].color;
c.a = f(points[i].position, t) >= threshold ? 1f : 0f;
points[i].color = c;
}
}
else {
for (int i = 0; i < points.Length; i++) {
Color c = points[i].color;
c.a = f(points[i].position, t);
points[i].color = c;
}
}
particleSystem.SetParticles(points, points.Length);
}
 
private static float Linear (Vector3 p, float t) {
return 1f - p.x - p.y - p.z + 0.5f * Mathf.Sin(t);
}
 
private static float Exponential (Vector3 p, float t) {
return 1f - p.x * p.x - p.y * p.y - p.z * p.z + 0.5f * Mathf.Sin(t);
}
 
private static float Parabola (Vector3 p, float t){
p.x += p.x - 1f;
p.z += p.z - 1f;
return 1f - p.x * p.x - p.z * p.z + 0.5f * Mathf.Sin(t);
}
 
private static float Sine (Vector3 p, float t){
float x = Mathf.Sin(2 * Mathf.PI * p.x);
float y = Mathf.Sin(2 * Mathf.PI * p.y);
float z = Mathf.Sin(2 * Mathf.PI * p.z + (p.y > 0.5f ? t : -t));
return x * x * y * y * z * z;
}
 
private static float Ripple (Vector3 p, float t){
p.x -= 0.5f;
p.y -= 0.5f;
p.z -= 0.5f;
float squareRadius = p.x * p.x + p.y * p.y + p.z * p.z;
return Mathf.Sin(4f * Mathf.PI * squareRadius - 2f * t);
}
}


锋芒毕露的物体

现在我们能够用数据来制作三个维度的图形了!有可能制作非常错综复杂的立体图形,只要你有足够的想象力和数学知识。

Downloads:

graphs.unitypackage

Graphs, visualizing data

这是《图表 可视化数据》的英文原文链接,感兴趣的同学们可以看一看。


建议使用电驴(eMule)下载分享的资源。

说明
:本教程来源互联网或网友分享或出版商宣传分享,仅为学习研究或媒体推广,51zixue.net不保证资料的完整性。
 
上一篇:【Unity C#编程】图表 可视化数据:添加多个维度  下一篇:【Unity C#编程】跑动游戏(6):GUI和粒子特效