鼎鼎大名的贝塞尔曲线相信大家都耳熟能详。这两天因为工作的原因需要将贝塞尔曲线加在工程中,那么MOMO迅速的研究了一下成果就分享给大家了哦。贝塞尔曲线的原理是由两个点构成的任意角度的曲线,这两个点一个是起点,一个是终点。在这条曲线之上还会有两个可以任意移动的点来控制贝塞尔曲线的角度。如下图所示,点1 和点4 就是起点和终点,点2 和点3 就是控制曲线角度的两个动态点。

如下图所示。使用拖动条来让曲线发生旋转,大家会看的更加清晰。目前我们看到的被塞尔曲线是在平面中完成的,其实贝塞尔曲线是完全 支持3D中完成,这里是为了让大家看的更加清楚MOMO将忽略Z曲线的Z轴。UnityAPI文档中有贝塞尔曲线的方法,可是只支持编辑器中使用,也就是 说无法在程序中使用。那么本篇文章我们利用贝塞尔曲线的数学原理以及LineRenderer组件来完成在Unity中使用贝塞尔曲线。

创建一个U3D的工程,创建一个新游戏对象,绑定LineRenderer组件。

Bezier.cs 这里是贝塞尔曲线的公式C#版本

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

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

usingUnityEngine;

[System.Serializable]

publicclassBezier:System.Object

{

publicVector3 p0;

publicVector3 p1;

publicVector3 p2;

publicVector3 p3;

publicfloatti=0f;

privateVector3 b0=Vector3.zero;

privateVector3 b1=Vector3.zero;

privateVector3 b2=Vector3.zero;

privateVector3 b3=Vector3.zero;

privatefloatAx;

privatefloatAy;

privatefloatAz;

privatefloatBx;

privatefloatBy;

privatefloatBz;

privatefloatCx;

privatefloatCy;

privatefloatCz;

// Init function v0 = 1st point, v1 = handle of the 1st point , v2 = handle of the 2nd point, v3 = 2nd point

// handle1 = v0 + v1

// handle2 = v3 + v2

publicBezier(Vector3 v0,Vector3 v1,Vector3 v2,Vector3 v3)

{

this.p0=v0;

this.p1=v1;

this.p2=v2;

this.p3=v3;

}

// 0.0 >= t <= 1.0

publicVector3 GetPointAtTime(floatt)

{

this.CheckConstant();

floatt2=t*t;

floatt3=t*t*t;

floatx=this.Ax*t3+this.Bx*t2+this.Cx*t+p0.x;

floaty=this.Ay*t3+this.By*t2+this.Cy*t+p0.y;

floatz=this.Az*t3+this.Bz*t2+this.Cz*t+p0.z;

returnnewVector3(x,y,z);

}

privatevoidSetConstant()

{

this.Cx=3f*((this.p0.x+this.p1.x)-this.p0.x);

this.Bx=3f*((this.p3.x+this.p2.x)-(this.p0.x+this.p1.x))-this.Cx;

this.Ax=this.p3.x-this.p0.x-this.Cx-this.Bx;

this.Cy=3f*((this.p0.y+this.p1.y)-this.p0.y);

this.By=3f*((this.p3.y+this.p2.y)-(this.p0.y+this.p1.y))-this.Cy;

this.Ay=this.p3.y-this.p0.y-this.Cy-this.By;

this.Cz=3f*((this.p0.z+this.p1.z)-this.p0.z);

this.Bz=3f*((this.p3.z+this.p2.z)-(this.p0.z+this.p1.z))-this.Cz;

this.Az=this.p3.z-this.p0.z-this.Cz-this.Bz;

}

// Check if p0, p1, p2 or p3 have changed

privatevoidCheckConstant()

{

if(this.p0!=this.b0||this.p1!=this.b1||this.p2!=this.b2||this.p3!=this.b3)

{

this.SetConstant();

this.b0=this.p0;

this.b1=this.p1;

this.b2=this.p2;

this.b3=this.p3;

}

}

}

MyBezier.cs 把它直接挂在摄像机上 ,控制拖动条来控制贝塞尔曲线、

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

usingUnityEngine;

publicclassMyBezier:MonoBehaviour

{

//贝塞尔曲线算法类

publicBezier myBezier;

//曲线的对象

publicGameObject Yellowline;

//曲线对象的曲线组件

privateLineRenderer YellowlineRenderer;

//拖动条用来控制贝塞尔曲线的两个点

publicfloathSliderValue0;

publicfloathSliderValue1;

voidStart()

{

//得到曲线组件

YellowlineRenderer=Yellowline.GetComponent();

//为了让曲线更加美观,设置曲线由100个点来组成

YellowlineRenderer.SetVertexCount(100);

}

voidOnGUI()

{

//拖动条得出 -5.0 - 5.0之间的一个数值

hSliderValue0=GUI.HorizontalSlider(newRect(25,25,100,30),hSliderValue0,-5.0F,5.0F);

hSliderValue1=GUI.HorizontalSlider(newRect(25,70,100,30),hSliderValue1,-5.0F,5.0F);

}

voidUpdate()

{

//在这里来计算贝塞尔曲线

//四个参数 表示当前贝塞尔曲线上的4个点 第一个点和第四个点

//我们是不需要移动的,中间的两个点是由拖动条来控制的。

myBezier=newBezier(newVector3(-5f,0f,0f),newVector3(hSliderValue1,hSliderValue0,0f),newVector3(hSliderValue1,hSliderValue0,0f),newVector3(5f,0f,0f));

//循环100遍来绘制贝塞尔曲线每个线段

for(inti=1;i<=100;i++)

{

//参数的取值范围 0 - 1 返回曲线没一点的位置

//为了精确这里使用i * 0.01 得到当前点的坐标

Vector3 vec=myBezier.GetPointAtTime((float)(i*0.01));

//把每条线段绘制出来 完成白塞尔曲线的绘制

YellowlineRenderer.SetPosition(i-1,vec);

}

}

}

OK 这里贝塞尔曲线的原理就已经完毕。下面我们学习在NGUI中如何使用贝塞尔曲线。刚刚我们说过贝塞尔曲线是由2个固定点 加两个动态点来完成的,其实我们在开发中往往只需要3个点。1 起点 2 中间点 3 结束点 拖动这三个点都可以重新计算曲线的轨迹这样才比较完美。如下图所示,这三个点都是可以任意拖动的,拖动结束后,黑色的线为用户拖拽点连接的直角线段,我们 根据这三个点组成的直角线段计算它们之间的贝塞尔曲线,也就是图中黄色的线段。

简单的进行拖拽一下,是不是感觉贝塞尔曲线很酷炫呢?哇咔咔。

我们来看看代码实现的部分,其实原理和上面完全一样。

BallMove.cs绑定在这三个可以拖拽的点上,让拖动小球后小球可跟随手指移动。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

usingUnityEngine;

usingSystem.Collections;

publicclassBallMove:MonoBehaviour

{

voidOnDrag(Vector2 delta)

{

floatmovex=transform.localPosition.x+(delta.x/3);

floatmovey=transform.localPosition.y+(delta.y/3);

//避免越界操作,这里可以进行一些判断

transform.localPosition=newVector3(movex,movey,transform.localPosition.z);

}

}

如此一来触摸小球后,小球将跟随用户手指移动。下面我们将监听用户触摸小球后的坐标来计算它们三点之间的贝塞尔曲线。

BallInit.cs挂在摄像机上

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

usingUnityEngine;

usingSystem.Collections;

publicclassBallInit:MonoBehaviour{

//黑色直角线段

LineRenderer lineRenderer0;

LineRenderer lineRenderer1;

//贝塞尔曲线

LineRenderer BezierRenderer;

//三个小球触摸对象

publicGameObject mark0;

publicGameObject mark1;

publicGameObject mark2;

//算法公式类

privateBezier myBezier;

voidStart()

{

//分别得到黑色直角线段 与黄色贝塞尔曲线的 线段组件

lineRenderer0=GameObject.Find("line0").GetComponent();

lineRenderer1=GameObject.Find("line1").GetComponent();

BezierRenderer=GameObject.Find("Bezier").GetComponent();

//黑色直角是有两个线段组成

lineRenderer0.SetVertexCount(2);

lineRenderer1.SetVertexCount(2);

//为了让贝塞尔曲线细致一些 设置它有100个点组成

BezierRenderer.SetVertexCount(100);

}

voidUpdate()

{

//mark0 表示中间的小球

//mark1 表示右边的小球

//mark2 表示左边的小球

//中间的标志点分别减去左右两边的标志点,计算出曲线的X Y 的点

floaty=(mark0.transform.position.y-mark2.transform.position.y);

floatx=(mark0.transform.position.x-mark2.transform.position.x);

//因为我们是通过3个点来确定贝塞尔曲线, 所以参数3 设置为0 即可。

//这样参数1 表示起点 参数2表示中间点 参数3 忽略 参数4 表示结束点

myBezier=newBezier(mark2.transform.position,newVector3(x,y,0f),newVector3(0f,0f,0f),mark1.transform.position);

//绘制贝塞尔曲线

for(inti=1;i<=100;i++)

{

Vector3 vec=myBezier.GetPointAtTime((float)(i*0.01));

BezierRenderer.SetPosition(i-1,vec);

}

//绘制直角黑色标志线段

lineRenderer0.SetPosition(0,mark0.transform.position);

lineRenderer0.SetPosition(1,mark2.transform.position);

lineRenderer1.SetPosition(0,mark0.transform.position);

lineRenderer1.SetPosition(1,mark1.transform.position);

}

}

unity 控制点 贝塞尔曲线_在Unity中使用贝塞尔曲线(转)相关推荐

  1. python绘制缓和曲线_在cad中画缓和曲线的绘制方法

    缓和曲线具有以下作用:曲率连续变化,便于车辆遵循:离心加速度逐渐变化,旅客感觉舒适:超高横坡度及加宽逐渐变化,行车更加稳定:与圆曲线配合,增加线形美观.故,缓和曲线在公路.桥梁.铁路及高速铁路中广泛采 ...

  2. 光滑曲线_计算机图形学十:贝塞尔曲线与贝塞尔曲面

    贝塞尔曲线与贝塞尔曲面 1 贝塞尔曲线(Bézier Curves) 在进入具体原理讲解之前,首先看一下一条实际的贝塞尔曲线长什么样子 其中 为 控制点,蓝色所表示曲线正是非常著名的贝塞尔曲线了,可以 ...

  3. unity 删除子节点_【Unity文档】Realtime GI介绍(一)

    * 介绍 Unity中,有两种GI的技术:烘焙(Baked)和预计算实时(Precomputed Realtime)全局光照,这篇是讲预计算实时部分的 目录 如何决定光图分辨率 光图中的Charts是 ...

  4. unity 3d游戏开发_使用Unity 5开发3D游戏

    unity 3d游戏开发 If there's one thing cooler than playing games, it's building games. 如果有比玩游戏更酷的一件事,那就是构 ...

  5. matlibplot 一张图画多个曲线_热重法实验条件设定与曲线解析 第53部分 热重实验方案设计与曲线解析常见问题之热重仪选择中常见问题分析...

    在本系列内容第49部分至第52部分中分别介绍了在不同的应用领域中热重曲线解析的常见方法,自本部分内容开始将陆续介绍在热重实验方案设计和曲线解析中的常见问题,在本部分内容中将介绍在热重实验方案设计中选择 ...

  6. 组态王怎么做超级曲线_组态王如何将历史曲线导出到电子表格中去?:

    高分求助:组态王实时报表通过按钮保存成excel格式怎么做? 看我的例子: String filename; string hour=StrFromReal(\\本站点\$时,0,"f&qu ...

  7. python怎么画出圆润的曲线_利用python画出AUC曲线的实例

    以load_breast_cancer数据集为例,模型细节不重要,重点是画AUC的代码. 直接上代码: from sklearn.datasets import load_breast_cancer ...

  8. 光滑曲线_消防水泵-流量扬程性能曲线

    石峥嵘,消防资源网创始人,消防大讲堂主讲人,从业消防25年,参与近千项目设计施工,解答消防疑问数万条,极为资深的实践经验,结合深厚理论基础,汇集金典,奉献大家! 石峥嵘:消防水泵的性能应满足消防给水系 ...

  9. 利用python画曲线_利用python画出AUC曲线的实例

    以load_breast_cancer数据集为例,模型细节不重要,重点是画AUC的代码.1XS免费资源网 直接上代码:1XS免费资源网 from sklearn.datasets import loa ...

最新文章

  1. 用js取1-100的随机数
  2. ubuntu 开启关闭mysql 服务
  3. 浪潮linux网卡驱动,浪潮NF5280M5安装redhat7.2下网卡驱动
  4. java mvc引擎_Velocity是一种Java模版引擎技术,MVC架构的一种实现,但它更多的是关注在Model和View之间,作为它们的桥梁。服务端渲染,我们使用最多的就是用他...
  5. jzoj6310-Global warming【线段树,LIS】
  6. Android之Notification初识
  7. Hive 大小表关联查询异常
  8. Step By Step(Lua字符串库)
  9. OpenShift 4 - 为客户端配置使用基于CA证书的kubeconfig实现无密码登录
  10. 刚入行的测试工程师如何自学软件测试【下篇】-- 软实力
  11. eclipse打不开,报错 java was started with exit code=13
  12. pip环境变量配置 python3.6_零基础学python之爬虫第一节环境配置第一章:Python3+Pip环境配置...
  13. 超好用的Redis管理及监控工具:TreeNMS
  14. 36.windbg-!peb(手工分析PEB结构)
  15. 视频截图获取视频某一帧做图片
  16. 蒂姆-库克于2010年5月14日在奥本大学毕业典礼上发表的演讲全文
  17. c语言中数的表示 叙述正确,关于C语言中数的表示,以下叙述正确的是(
  18. 加速C++程序编译的方法
  19. wordpress外贸跨境电商独立站WooCommerce插件安装教程
  20. 微信里直接打开微博APP的方法

热门文章

  1. RGB的光的三原色、品红黄青颜料的三原色
  2. python三原色组合白色_为何色光三原色三三相加得到白色,这其中加色原理是如何起作用的?...
  3. linux配置iscsi无账号密码,linux iscsi Initiator配置CHAP认证
  4. Linux ip forward转发问题总结
  5. Vs2008编译vtk5.10详细教程
  6. Kubernetes中RBAC实战一 servicecount 10月2日实验笔记
  7. 每天学命令all_inputs
  8. Excavator(挖掘机)-Java RMI
  9. 人工智能时代:软件中的人工智能将如何改变程序员的角色
  10. Luogu1197 星球大战