1
+ /*************************************************************************
2
+ * Copyright © 2017-2018 Mogoson. All rights reserved.
3
+ *------------------------------------------------------------------------
4
+ * File : BezierCurve.cs
5
+ * Description : Define bezier curve.
6
+ *------------------------------------------------------------------------
7
+ * Author : Mogoson
8
+ * Version : 0.1.0
9
+ * Date : 1/7/2017
10
+ * Description : Initial development version.
11
+ *
12
+ * Author : Mogoson
13
+ * Version : 0.1.1
14
+ * Date : 2/28/2018
15
+ * Description : Add static method GetPoint.
16
+ *************************************************************************/
17
+
18
+ using System ;
19
+ using UnityEngine ;
20
+
21
+ namespace Mogoson . Curve
22
+ {
23
+ /// <summary>
24
+ /// Anchor points of linear bezier curve.
25
+ /// </summary>
26
+ [ Serializable ]
27
+ public struct LinearBezierAnchor
28
+ {
29
+ #region Field and Property
30
+ /// <summary>
31
+ /// Start point of curve.
32
+ /// </summary>
33
+ public Vector3 start ;
34
+
35
+ /// <summary>
36
+ /// End point of curve.
37
+ /// </summary>
38
+ public Vector3 end ;
39
+ #endregion
40
+
41
+ #region Public Method
42
+ /// <summary>
43
+ /// Constructor.
44
+ /// </summary>
45
+ /// <param name="start">Start point of curve.</param>
46
+ /// <param name="end">End point of curve.</param>
47
+ public LinearBezierAnchor ( Vector3 start , Vector3 end )
48
+ {
49
+ this . start = start ;
50
+ this . end = end ;
51
+ }
52
+ #endregion
53
+ }
54
+
55
+ /// <summary>
56
+ /// Anchor points of quadratic bezier curve.
57
+ /// </summary>
58
+ [ Serializable ]
59
+ public struct QuadraticBezierAnchor
60
+ {
61
+ #region Field and Property
62
+ /// <summary>
63
+ /// Start point of curve.
64
+ /// </summary>
65
+ public Vector3 start ;
66
+
67
+ /// <summary>
68
+ /// End point of curve.
69
+ /// </summary>
70
+ public Vector3 end ;
71
+
72
+ /// <summary>
73
+ /// Tangent point of curve.
74
+ /// </summary>
75
+ public Vector3 tangent ;
76
+ #endregion
77
+
78
+ #region Public Method
79
+ /// <summary>
80
+ /// Constructor.
81
+ /// </summary>
82
+ /// <param name="start">Start point of curve.</param>
83
+ /// <param name="end">End point of curve.</param>
84
+ /// <param name="tangent">Tangent point of curve.</param>
85
+ public QuadraticBezierAnchor ( Vector3 start , Vector3 end , Vector3 tangent )
86
+ {
87
+ this . start = start ;
88
+ this . end = end ;
89
+ this . tangent = tangent ;
90
+ }
91
+ #endregion
92
+ }
93
+
94
+ /// <summary>
95
+ /// Anchor points of cubic bezier curve.
96
+ /// </summary>
97
+ [ Serializable ]
98
+ public struct CubicBezierAnchor
99
+ {
100
+ #region Field and Property
101
+ /// <summary>
102
+ /// Start point of curve.
103
+ /// </summary>
104
+ public Vector3 start ;
105
+
106
+ /// <summary>
107
+ /// End point of curve.
108
+ /// </summary>
109
+ public Vector3 end ;
110
+
111
+ /// <summary>
112
+ /// Start tangent point of curve.
113
+ /// </summary>
114
+ public Vector3 startTangent ;
115
+
116
+ /// <summary>
117
+ /// End tangent point of curve.
118
+ /// </summary>
119
+ public Vector3 endTangent ;
120
+ #endregion
121
+
122
+ #region Public Method
123
+ /// <summary>
124
+ /// Constructor.
125
+ /// </summary>
126
+ /// <param name="start">Start point of curve.</param>
127
+ /// <param name="end">End point of curve.</param>
128
+ /// <param name="startTangent">Start tangent point of curve.</param>
129
+ /// <param name="endTangent">End tangent point of curve.</param>
130
+ public CubicBezierAnchor ( Vector3 start , Vector3 end , Vector3 startTangent , Vector3 endTangent )
131
+ {
132
+ this . start = start ;
133
+ this . end = end ;
134
+ this . startTangent = startTangent ;
135
+ this . endTangent = endTangent ;
136
+ }
137
+ #endregion
138
+ }
139
+
140
+ /// <summary>
141
+ /// Bezier curve.
142
+ /// </summary>
143
+ public abstract class BezierCurve : ICurve
144
+ {
145
+ #region Field and Property
146
+ /// <summary>
147
+ /// Delta to lerp key.
148
+ /// </summary>
149
+ protected const float Delta = 0.05f ;
150
+
151
+ /// <summary>
152
+ /// Length of curve.
153
+ /// </summary>
154
+ public float Length
155
+ {
156
+ get
157
+ {
158
+ var length = 0.0f ;
159
+ for ( float key = 0 ; key < MaxKey ; key += Delta )
160
+ {
161
+ length += Vector3 . Distance ( GetPointAt ( key ) , GetPointAt ( key + Delta ) ) ;
162
+ }
163
+ return length ;
164
+ }
165
+ }
166
+
167
+ /// <summary>
168
+ /// Max key of curve.
169
+ /// </summary>
170
+ public float MaxKey { get { return 1.0f ; } }
171
+ #endregion
172
+
173
+ #region Public Method
174
+ /// <summary>
175
+ /// Get point on curve at key.
176
+ /// </summary>
177
+ /// <param name="key">Key is in the range(0~1).</param>
178
+ /// <returns>The point on curve at key.</returns>
179
+ public abstract Vector3 GetPointAt ( float key ) ;
180
+ #endregion
181
+ }
182
+
183
+ /// <summary>
184
+ /// Linear bezier curve.
185
+ /// </summary>
186
+ public class LinearBezierCurve : BezierCurve
187
+ {
188
+ #region Field and Property
189
+ /// <summary>
190
+ /// Anchor points of curve.
191
+ /// </summary>
192
+ public LinearBezierAnchor anchor ;
193
+ #endregion
194
+
195
+ #region Public Method
196
+ /// <summary>
197
+ /// Constructor.
198
+ /// </summary>
199
+ public LinearBezierCurve ( )
200
+ {
201
+ anchor = new LinearBezierAnchor ( ) ;
202
+ }
203
+
204
+ /// <summary>
205
+ /// Constructor.
206
+ /// </summary>
207
+ /// <param name="anchor">Anchor points of curve.</param>
208
+ public LinearBezierCurve ( LinearBezierAnchor anchor )
209
+ {
210
+ this . anchor = anchor ;
211
+ }
212
+
213
+ /// <summary>
214
+ /// Get point on curve at key.
215
+ /// </summary>
216
+ /// <param name="key">Key is in the range(0~1).</param>
217
+ /// <returns>The point on curve at key.</returns>
218
+ public override Vector3 GetPointAt ( float key )
219
+ {
220
+ return GetPointAt ( anchor , key ) ;
221
+ }
222
+ #endregion
223
+
224
+ #region Static Method
225
+ /// <summary>
226
+ /// Get curve point base on anchor points and key.
227
+ /// </summary>
228
+ /// <param name="anchor">Anchor points of curve.</param>
229
+ /// <param name="key">Key is in the range(0~1).</param>
230
+ /// <returns>Point on curve.</returns>
231
+ public static Vector3 GetPointAt ( LinearBezierAnchor anchor , float key )
232
+ {
233
+ return ( 1 - key ) * anchor . start + key * anchor . end ;
234
+ }
235
+ #endregion
236
+ }
237
+
238
+ /// <summary>
239
+ /// Quadratic bezier curve.
240
+ /// </summary>
241
+ public class QuadraticBezierCurve : BezierCurve
242
+ {
243
+ #region Field and Property
244
+ /// <summary>
245
+ /// Anchor points of curve.
246
+ /// </summary>
247
+ public QuadraticBezierAnchor anchor ;
248
+ #endregion
249
+
250
+ #region Public Method
251
+ /// <summary>
252
+ /// Constructor.
253
+ /// </summary>
254
+ public QuadraticBezierCurve ( )
255
+ {
256
+ anchor = new QuadraticBezierAnchor ( ) ;
257
+ }
258
+
259
+ /// <summary>
260
+ /// Constructor.
261
+ /// </summary>
262
+ /// <param name="anchor">Anchor points of curve.</param>
263
+ public QuadraticBezierCurve ( QuadraticBezierAnchor anchor )
264
+ {
265
+ this . anchor = anchor ;
266
+ }
267
+
268
+ /// <summary>
269
+ /// Get point on curve at key.
270
+ /// </summary>
271
+ /// <param name="key">Key is in the range(0~1).</param>
272
+ /// <returns>The point on curve at key.</returns>
273
+ public override Vector3 GetPointAt ( float key )
274
+ {
275
+ return GetPointAt ( anchor , key ) ;
276
+ }
277
+ #endregion
278
+
279
+ #region Static Method
280
+ /// <summary>
281
+ /// Get curve point base on anchor points and key.
282
+ /// </summary>
283
+ /// <param name="anchor">Anchor points of curve.</param>
284
+ /// <param name="key">Key is in the range(0~1).</param>
285
+ /// <returns>Point on curve.</returns>
286
+ public static Vector3 GetPointAt ( QuadraticBezierAnchor anchor , float t )
287
+ {
288
+ return Mathf . Pow ( 1 - t , 2 ) * anchor . start + 2 * t * ( 1 - t ) * anchor . tangent + Mathf . Pow ( t , 2 ) * anchor . end ;
289
+ }
290
+ #endregion
291
+ }
292
+
293
+ /// <summary>
294
+ /// Cubic bezier curve.
295
+ /// </summary>
296
+ public class CubicBezierCurve : BezierCurve
297
+ {
298
+ #region Field and Property
299
+ /// <summary>
300
+ /// Anchor points of curve.
301
+ /// </summary>
302
+ public CubicBezierAnchor anchor ;
303
+ #endregion
304
+
305
+ #region Public Method
306
+ /// <summary>
307
+ /// Constructor.
308
+ /// </summary>
309
+ public CubicBezierCurve ( )
310
+ {
311
+ anchor = new CubicBezierAnchor ( ) ;
312
+ }
313
+
314
+ /// <summary>
315
+ /// Constructor.
316
+ /// </summary>
317
+ /// <param name="anchor">Anchor points of curve.</param>
318
+ public CubicBezierCurve ( CubicBezierAnchor anchor )
319
+ {
320
+ this . anchor = anchor ;
321
+ }
322
+
323
+ /// <summary>
324
+ /// Get point on curve at key.
325
+ /// </summary>
326
+ /// <param name="key">Key is in the range(0~1).</param>
327
+ /// <returns>The point on curve at key.</returns>
328
+ public override Vector3 GetPointAt ( float key )
329
+ {
330
+ return GetPointAt ( anchor , key ) ;
331
+ }
332
+ #endregion
333
+
334
+ #region Static Method
335
+ /// <summary>
336
+ /// Get curve point base on anchor points and key.
337
+ /// </summary>
338
+ /// <param name="anchor">Anchor points of curve.</param>
339
+ /// <param name="key">Key is in the range(0~1).</param>
340
+ /// <returns>Point on curve.</returns>
341
+ public static Vector3 GetPointAt ( CubicBezierAnchor anchor , float key )
342
+ {
343
+ return Mathf . Pow ( 1 - key , 3 ) * anchor . start + 3 * key * Mathf . Pow ( 1 - key , 2 ) * anchor . startTangent +
344
+ 3 * ( 1 - key ) * Mathf . Pow ( key , 2 ) * anchor . endTangent + Mathf . Pow ( key , 3 ) * anchor . end ;
345
+ }
346
+ #endregion
347
+ }
348
+ }
0 commit comments