Easing.cs 71 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324
  1. // Animancer // https://kybernetik.com.au/animancer // Copyright 2018-2024 Kybernetik //
  2. using System;
  3. using static UnityEngine.Mathf;
  4. using NormalizedDelegate = System.Func<float, float>;
  5. namespace Animancer
  6. {
  7. /// <summary>A set of common <see href="https://easings.net">easing functions</see>.</summary>
  8. /// <remarks>
  9. /// There are several different types of functions:
  10. /// <list type="bullet">
  11. /// <item>In: accelerating from zero velocity.</item>
  12. /// <item>Out: decelerating to zero velocity.</item>
  13. /// <item>InOut: uses the corresponding In function until halfway, then the Out function after that.</item>
  14. /// <item>Normalized: methods with a single parameter (<see cref="float"/> value) expect values from 0 to 1.</item>
  15. /// <item>Ranged: methods with 3 parameters (<see cref="float"/> start, <see cref="float"/> end,
  16. /// <see cref="float"/> value) use the specified range instead ot 0 to 1.</item>
  17. /// <item>Derivative: calculates the gradient of their corresponding non-derivative function.
  18. /// The more complex derivative functions were made with 'https://www.derivative-calculator.net'.</item>
  19. /// </list>
  20. /// </remarks>
  21. /// https://kybernetik.com.au/animancer/api/Animancer/Easing
  22. ///
  23. public static class Easing
  24. {
  25. /************************************************************************************************************************/
  26. #region Delegates
  27. /************************************************************************************************************************/
  28. /// <summary>The natural log of 2.</summary>
  29. public const float Ln2 = 0.693147180559945f;
  30. /************************************************************************************************************************/
  31. /// <summary>A variant of a <see cref="NormalizedDelegate"/> with a custom range instead of 0 to 1.</summary>
  32. public delegate float RangedDelegate(float start, float end, float value);
  33. /************************************************************************************************************************/
  34. /// <summary>The name of an easing function.</summary>
  35. /// <remarks>The <see cref="Easing"/> class contains various extension methods for this enum.</remarks>
  36. /// https://kybernetik.com.au/animancer/api/Animancer/Function
  37. ///
  38. public enum Function
  39. {
  40. /// <summary><see cref="Easing.Linear(float)"/></summary>
  41. Linear,
  42. /// <summary><see cref="Quadratic.In(float)"/></summary>
  43. QuadraticIn,
  44. /// <summary><see cref="Quadratic.Out(float)"/></summary>
  45. QuadraticOut,
  46. /// <summary><see cref="Quadratic.InOut(float)"/></summary>
  47. QuadraticInOut,
  48. /// <summary><see cref="Cubic.In(float)"/></summary>
  49. CubicIn,
  50. /// <summary><see cref="Cubic.Out(float)"/></summary>
  51. CubicOut,
  52. /// <summary><see cref="Cubic.InOut(float)"/></summary>
  53. CubicInOut,
  54. /// <summary><see cref="Quartic.In(float)"/></summary>
  55. QuarticIn,
  56. /// <summary><see cref="Quartic.Out(float)"/></summary>
  57. QuarticOut,
  58. /// <summary><see cref="Quartic.InOut(float)"/></summary>
  59. QuarticInOut,
  60. /// <summary><see cref="Quintic.In(float)"/></summary>
  61. QuinticIn,
  62. /// <summary><see cref="Quintic.Out(float)"/></summary>
  63. QuinticOut,
  64. /// <summary><see cref="Quintic.InOut(float)"/></summary>
  65. QuinticInOut,
  66. /// <summary><see cref="Sine.In(float)"/></summary>
  67. SineIn,
  68. /// <summary><see cref="Sine.Out(float)"/></summary>
  69. SineOut,
  70. /// <summary><see cref="Sine.InOut(float)"/></summary>
  71. SineInOut,
  72. /// <summary><see cref="Exponential.In(float)"/></summary>
  73. ExponentialIn,
  74. /// <summary><see cref="Exponential.Out(float)"/></summary>
  75. ExponentialOut,
  76. /// <summary><see cref="Exponential.InOut(float)"/></summary>
  77. ExponentialInOut,
  78. /// <summary><see cref="Circular.In(float)"/></summary>
  79. CircularIn,
  80. /// <summary><see cref="Circular.Out(float)"/></summary>
  81. CircularOut,
  82. /// <summary><see cref="Circular.InOut(float)"/></summary>
  83. CircularInOut,
  84. /// <summary><see cref="Back.In(float)"/></summary>
  85. BackIn,
  86. /// <summary><see cref="Back.Out(float)"/></summary>
  87. BackOut,
  88. /// <summary><see cref="Back.InOut(float)"/></summary>
  89. BackInOut,
  90. /// <summary><see cref="Bounce.In(float)"/></summary>
  91. BounceIn,
  92. /// <summary><see cref="Bounce.Out(float)"/></summary>
  93. BounceOut,
  94. /// <summary><see cref="Bounce.InOut(float)"/></summary>
  95. BounceInOut,
  96. /// <summary><see cref="Elastic.In(float)"/></summary>
  97. ElasticIn,
  98. /// <summary><see cref="Elastic.Out(float)"/></summary>
  99. ElasticOut,
  100. /// <summary><see cref="Elastic.InOut(float)"/></summary>
  101. ElasticInOut,
  102. }
  103. /// <summary>The total number of <see cref="Function"/> values.</summary>
  104. public const int FunctionCount = (int)Function.ElasticInOut + 1;
  105. /************************************************************************************************************************/
  106. private static NormalizedDelegate[] _FunctionDelegates;
  107. /// <summary>[Animancer Extension]
  108. /// Returns a cached delegate representing the specified `function` with a normalized range.
  109. /// </summary>
  110. public static NormalizedDelegate GetDelegate(this Function function)
  111. {
  112. var i = (int)function;
  113. if (_FunctionDelegates == null)
  114. {
  115. _FunctionDelegates = new NormalizedDelegate[FunctionCount];
  116. }
  117. else
  118. {
  119. var del = _FunctionDelegates[i];
  120. if (del != null)
  121. return del;
  122. }
  123. return _FunctionDelegates[i] = function switch
  124. {
  125. Function.Linear => Linear,
  126. Function.QuadraticIn => Quadratic.In,
  127. Function.QuadraticOut => Quadratic.Out,
  128. Function.QuadraticInOut => Quadratic.InOut,
  129. Function.CubicIn => Cubic.In,
  130. Function.CubicOut => Cubic.Out,
  131. Function.CubicInOut => Cubic.InOut,
  132. Function.QuarticIn => Quartic.In,
  133. Function.QuarticOut => Quartic.Out,
  134. Function.QuarticInOut => Quartic.InOut,
  135. Function.QuinticIn => Quintic.In,
  136. Function.QuinticOut => Quintic.Out,
  137. Function.QuinticInOut => Quintic.InOut,
  138. Function.SineIn => Sine.In,
  139. Function.SineOut => Sine.Out,
  140. Function.SineInOut => Sine.InOut,
  141. Function.ExponentialIn => Exponential.In,
  142. Function.ExponentialOut => Exponential.Out,
  143. Function.ExponentialInOut => Exponential.InOut,
  144. Function.CircularIn => Circular.In,
  145. Function.CircularOut => Circular.Out,
  146. Function.CircularInOut => Circular.InOut,
  147. Function.BackIn => Back.In,
  148. Function.BackOut => Back.Out,
  149. Function.BackInOut => Back.InOut,
  150. Function.BounceIn => Bounce.In,
  151. Function.BounceOut => Bounce.Out,
  152. Function.BounceInOut => Bounce.InOut,
  153. Function.ElasticIn => Elastic.In,
  154. Function.ElasticOut => Elastic.Out,
  155. Function.ElasticInOut => Elastic.InOut,
  156. _ => throw new ArgumentOutOfRangeException(nameof(function)),
  157. };
  158. }
  159. /************************************************************************************************************************/
  160. private static NormalizedDelegate[] _DerivativeDelegates;
  161. /// <summary>[Animancer Extension]
  162. /// Returns a cached delegate representing the derivative of the specified `function` with a normalized range.
  163. /// </summary>
  164. public static NormalizedDelegate GetDerivativeDelegate(this Function function)
  165. {
  166. var i = (int)function;
  167. if (_DerivativeDelegates == null)
  168. {
  169. _DerivativeDelegates = new NormalizedDelegate[FunctionCount];
  170. }
  171. else
  172. {
  173. var del = _DerivativeDelegates[i];
  174. if (del != null)
  175. return del;
  176. }
  177. return _DerivativeDelegates[i] = function switch
  178. {
  179. Function.Linear => LinearDerivative,
  180. Function.QuadraticIn => Quadratic.InDerivative,
  181. Function.QuadraticOut => Quadratic.OutDerivative,
  182. Function.QuadraticInOut => Quadratic.InOutDerivative,
  183. Function.CubicIn => Cubic.InDerivative,
  184. Function.CubicOut => Cubic.OutDerivative,
  185. Function.CubicInOut => Cubic.InOutDerivative,
  186. Function.QuarticIn => Quartic.InDerivative,
  187. Function.QuarticOut => Quartic.OutDerivative,
  188. Function.QuarticInOut => Quartic.InOutDerivative,
  189. Function.QuinticIn => Quintic.InDerivative,
  190. Function.QuinticOut => Quintic.OutDerivative,
  191. Function.QuinticInOut => Quintic.InOutDerivative,
  192. Function.SineIn => Sine.InDerivative,
  193. Function.SineOut => Sine.OutDerivative,
  194. Function.SineInOut => Sine.InOutDerivative,
  195. Function.ExponentialIn => Exponential.InDerivative,
  196. Function.ExponentialOut => Exponential.OutDerivative,
  197. Function.ExponentialInOut => Exponential.InOutDerivative,
  198. Function.CircularIn => Circular.InDerivative,
  199. Function.CircularOut => Circular.OutDerivative,
  200. Function.CircularInOut => Circular.InOutDerivative,
  201. Function.BackIn => Back.InDerivative,
  202. Function.BackOut => Back.OutDerivative,
  203. Function.BackInOut => Back.InOutDerivative,
  204. Function.BounceIn => Bounce.InDerivative,
  205. Function.BounceOut => Bounce.OutDerivative,
  206. Function.BounceInOut => Bounce.InOutDerivative,
  207. Function.ElasticIn => Elastic.InDerivative,
  208. Function.ElasticOut => Elastic.OutDerivative,
  209. Function.ElasticInOut => Elastic.InOutDerivative,
  210. _ => throw new ArgumentOutOfRangeException(nameof(function)),
  211. };
  212. }
  213. /************************************************************************************************************************/
  214. private static RangedDelegate[] _RangedFunctionDelegates;
  215. /// <summary>[Animancer Extension]
  216. /// Returns a cached delegate representing the specified `function` with a custom range.
  217. /// </summary>
  218. public static RangedDelegate GetRangedDelegate(this Function function)
  219. {
  220. var i = (int)function;
  221. if (_RangedFunctionDelegates == null)
  222. {
  223. _RangedFunctionDelegates = new RangedDelegate[FunctionCount];
  224. }
  225. else
  226. {
  227. var del = _RangedFunctionDelegates[i];
  228. if (del != null)
  229. return del;
  230. }
  231. return _RangedFunctionDelegates[i] = function switch
  232. {
  233. Function.Linear => Linear,
  234. Function.QuadraticIn => Quadratic.In,
  235. Function.QuadraticOut => Quadratic.Out,
  236. Function.QuadraticInOut => Quadratic.InOut,
  237. Function.CubicIn => Cubic.In,
  238. Function.CubicOut => Cubic.Out,
  239. Function.CubicInOut => Cubic.InOut,
  240. Function.QuarticIn => Quartic.In,
  241. Function.QuarticOut => Quartic.Out,
  242. Function.QuarticInOut => Quartic.InOut,
  243. Function.QuinticIn => Quintic.In,
  244. Function.QuinticOut => Quintic.Out,
  245. Function.QuinticInOut => Quintic.InOut,
  246. Function.SineIn => Sine.In,
  247. Function.SineOut => Sine.Out,
  248. Function.SineInOut => Sine.InOut,
  249. Function.ExponentialIn => Exponential.In,
  250. Function.ExponentialOut => Exponential.Out,
  251. Function.ExponentialInOut => Exponential.InOut,
  252. Function.CircularIn => Circular.In,
  253. Function.CircularOut => Circular.Out,
  254. Function.CircularInOut => Circular.InOut,
  255. Function.BackIn => Back.In,
  256. Function.BackOut => Back.Out,
  257. Function.BackInOut => Back.InOut,
  258. Function.BounceIn => Bounce.In,
  259. Function.BounceOut => Bounce.Out,
  260. Function.BounceInOut => Bounce.InOut,
  261. Function.ElasticIn => Elastic.In,
  262. Function.ElasticOut => Elastic.Out,
  263. Function.ElasticInOut => Elastic.InOut,
  264. _ => throw new ArgumentOutOfRangeException(nameof(function)),
  265. };
  266. }
  267. /************************************************************************************************************************/
  268. private static RangedDelegate[] _RangedDerivativeDelegates;
  269. /// <summary>[Animancer Extension]
  270. /// Returns a cached delegate representing the derivative of the specified `function` with a custom range.
  271. /// </summary>
  272. public static RangedDelegate GetRangedDerivativeDelegate(this Function function)
  273. {
  274. var i = (int)function;
  275. if (_RangedDerivativeDelegates == null)
  276. {
  277. _RangedDerivativeDelegates = new RangedDelegate[FunctionCount];
  278. }
  279. else
  280. {
  281. var del = _RangedDerivativeDelegates[i];
  282. if (del != null)
  283. return del;
  284. }
  285. return _RangedDerivativeDelegates[i] = function switch
  286. {
  287. Function.Linear => LinearDerivative,
  288. Function.QuadraticIn => Quadratic.InDerivative,
  289. Function.QuadraticOut => Quadratic.OutDerivative,
  290. Function.QuadraticInOut => Quadratic.InOutDerivative,
  291. Function.CubicIn => Cubic.InDerivative,
  292. Function.CubicOut => Cubic.OutDerivative,
  293. Function.CubicInOut => Cubic.InOutDerivative,
  294. Function.QuarticIn => Quartic.InDerivative,
  295. Function.QuarticOut => Quartic.OutDerivative,
  296. Function.QuarticInOut => Quartic.InOutDerivative,
  297. Function.QuinticIn => Quintic.InDerivative,
  298. Function.QuinticOut => Quintic.OutDerivative,
  299. Function.QuinticInOut => Quintic.InOutDerivative,
  300. Function.SineIn => Sine.InDerivative,
  301. Function.SineOut => Sine.OutDerivative,
  302. Function.SineInOut => Sine.InOutDerivative,
  303. Function.ExponentialIn => Exponential.InDerivative,
  304. Function.ExponentialOut => Exponential.OutDerivative,
  305. Function.ExponentialInOut => Exponential.InOutDerivative,
  306. Function.CircularIn => Circular.InDerivative,
  307. Function.CircularOut => Circular.OutDerivative,
  308. Function.CircularInOut => Circular.InOutDerivative,
  309. Function.BackIn => Back.InDerivative,
  310. Function.BackOut => Back.OutDerivative,
  311. Function.BackInOut => Back.InOutDerivative,
  312. Function.BounceIn => Bounce.InDerivative,
  313. Function.BounceOut => Bounce.OutDerivative,
  314. Function.BounceInOut => Bounce.InOutDerivative,
  315. Function.ElasticIn => Elastic.InDerivative,
  316. Function.ElasticOut => Elastic.OutDerivative,
  317. Function.ElasticInOut => Elastic.InOutDerivative,
  318. _ => throw new ArgumentOutOfRangeException(nameof(function)),
  319. };
  320. }
  321. /************************************************************************************************************************/
  322. /// <summary>Returns a linearly interpolated value between the `start` and `end` based on a normalized `value`.</summary>
  323. /// <remarks>
  324. /// <list type="bullet">
  325. /// <item><c>value = 0</c> returns <c>start</c>.</item>
  326. /// <item><c>value = 0.5</c> returns <c>(start + end) / 2</c>.</item>
  327. /// <item><c>value = 1</c> returns <c>end</c>.</item>
  328. /// </list>
  329. /// This method is identical to <see cref="LerpUnclamped"/>.
  330. /// </remarks>
  331. public static float Lerp(float start, float end, float value) => start + (end - start) * value;
  332. /// <summary>Returns a normalized value indicating how far the `value` is between the `start` and `end`.</summary>
  333. /// <remarks>
  334. /// <list type="bullet">
  335. /// <item><c>value = start</c> returns <c>0</c>.</item>
  336. /// <item><c>value = (start + end) / 2</c> returns <c>0.5</c>.</item>
  337. /// <item><c>value = end</c> returns <c>1</c>.</item>
  338. /// <item><c>start = end</c> returns <c>0</c>.</item>
  339. /// </list>
  340. /// This method is like <see cref="InverseLerp"/> except that it doesn't clamp the result between 0 and 1.
  341. /// </remarks>
  342. public static float UnLerp(float start, float end, float value)
  343. => start == end
  344. ? 0
  345. : (value - start) / (end - start);
  346. /************************************************************************************************************************/
  347. /// <summary>Re-scales the result of the `function` to use a custom range instead of 0 to 1.</summary>
  348. public static float ReScale(float start, float end, float value, NormalizedDelegate function)
  349. => Lerp(start, end, function(UnLerp(start, end, value)));
  350. /************************************************************************************************************************/
  351. #endregion
  352. /************************************************************************************************************************/
  353. #region Linear
  354. /************************************************************************************************************************/
  355. /// <summary>Directly returns the `value`. Interpolates the `value` based on the line <c>y = x</c>.</summary>
  356. public static float Linear(float value) => value;
  357. /************************************************************************************************************************/
  358. /// <summary>Returns 1. The derivative of <see cref="Linear(float)"/>.</summary>
  359. public static float LinearDerivative(float value) => 1;
  360. /************************************************************************************************************************/
  361. /// <summary>Directly returns the `value`. Interpolates the `value` based on the line <c>y = x</c>.</summary>
  362. public static float Linear(float start, float end, float value) => value;
  363. /************************************************************************************************************************/
  364. /// <summary>Returns <c>end - start</c>. The derivative of <see cref="Linear(float, float, float)"/>.</summary>
  365. public static float LinearDerivative(float start, float end, float value) => end - start;
  366. /************************************************************************************************************************/
  367. #endregion
  368. /************************************************************************************************************************/
  369. #region Quadratic
  370. /************************************************************************************************************************/
  371. /// <summary>Functions based on quadratic equations (<c>x^2</c>).</summary>
  372. /// https://kybernetik.com.au/animancer/api/Animancer/Quadratic
  373. ///
  374. public static class Quadratic
  375. {
  376. /************************************************************************************************************************/
  377. /// <summary>Interpolates the `value` based on the line <c>y = x^2</c>.</summary>
  378. /// <remarks><see href="https://easings.net/#easeInQuad">Easings.net has a graph of this function.</see></remarks>
  379. public static float In(float value) => value * value;
  380. /// <summary>Interpolates the `value` based on the line <c>y = 1 - (x - 1)^2</c>.</summary>
  381. /// <remarks><see href="https://easings.net/#easeOutQuad">Easings.net has a graph of this function.</see></remarks>
  382. public static float Out(float value)
  383. {
  384. value--;
  385. return -value * value + 1;
  386. }
  387. /// <summary>Interpolate using <see cref="In"/> (0 to 0.5) or <see cref="Out"/> (0.5 to 1).</summary>
  388. /// <remarks><see href="https://easings.net/#easeInOutQuad">Easings.net has a graph of this function.</see></remarks>
  389. public static float InOut(float value)
  390. {
  391. value *= 2;
  392. if (value <= 1)
  393. {
  394. return 0.5f * value * value;
  395. }
  396. else
  397. {
  398. value -= 2;
  399. return 0.5f * (-value * value + 2);
  400. }
  401. }
  402. /************************************************************************************************************************/
  403. /// <summary>Returns the derivative of <see cref="In(float)"/> (<c>y = 2x</c>).</summary>
  404. public static float InDerivative(float value) => 2 * value;
  405. /// <summary>Returns the derivative of <see cref="Out(float)"/> (<c>y = -2x + 2</c>).</summary>
  406. public static float OutDerivative(float value) => 2 - 2 * value;
  407. /// <summary>Returns the derivative of <see cref="InOut(float)"/>.</summary>
  408. public static float InOutDerivative(float value)
  409. {
  410. value *= 2;
  411. if (value <= 1)
  412. {
  413. return 2 * value;
  414. }
  415. else
  416. {
  417. value--;
  418. return 2 - 2 * value;
  419. }
  420. }
  421. /************************************************************************************************************************/
  422. // Ranged Variants.
  423. /************************************************************************************************************************/
  424. /// <summary>A variant of <see cref="In(float)"/> with a custom range instead of 0 to 1.</summary>
  425. public static float In(float start, float end, float value) => Lerp(start, end, In(UnLerp(start, end, value)));
  426. /// <summary>A variant of <see cref="Out(float)"/> with a custom range instead of 0 to 1.</summary>
  427. public static float Out(float start, float end, float value) => Lerp(start, end, Out(UnLerp(start, end, value)));
  428. /// <summary>A variant of <see cref="InOut(float)"/> with a custom range instead of 0 to 1.</summary>
  429. public static float InOut(float start, float end, float value) => Lerp(start, end, InOut(UnLerp(start, end, value)));
  430. /// <summary>A variant of <see cref="InDerivative(float)"/> with a custom range instead of 0 to 1.</summary>
  431. public static float InDerivative(float start, float end, float value) => InDerivative(UnLerp(start, end, value)) * (end - start);
  432. /// <summary>A variant of <see cref="InDerivative(float)"/> with a custom range instead of 0 to 1.</summary>
  433. public static float OutDerivative(float start, float end, float value) => OutDerivative(UnLerp(start, end, value)) * (end - start);
  434. /// <summary>A variant of <see cref="InDerivative(float)"/> with a custom range instead of 0 to 1.</summary>
  435. public static float InOutDerivative(float start, float end, float value) => InOutDerivative(UnLerp(start, end, value)) * (end - start);
  436. /************************************************************************************************************************/
  437. }
  438. /************************************************************************************************************************/
  439. #endregion
  440. /************************************************************************************************************************/
  441. #region Cubic
  442. /************************************************************************************************************************/
  443. /// <summary>Functions based on cubic equations (<c>x^3</c>).</summary>
  444. /// https://kybernetik.com.au/animancer/api/Animancer/Cubic
  445. ///
  446. public static class Cubic
  447. {
  448. /************************************************************************************************************************/
  449. /// <summary>Interpolates the `value` based on the line <c>y = x^3</c>.</summary>
  450. /// <remarks><see href="https://easings.net/#easeInCubic">Easings.net has a graph of this function.</see></remarks>
  451. public static float In(float value) => value * value * value;
  452. /// <summary>Interpolates the `value` based on the line <c>y = 1 + (x - 1)^3</c>.</summary>
  453. /// <remarks><see href="https://easings.net/#easeOutCubic">Easings.net has a graph of this function.</see></remarks>
  454. public static float Out(float value)
  455. {
  456. value--;
  457. return value * value * value + 1;
  458. }
  459. /// <summary>Interpolate using <see cref="In"/> (0 to 0.5) or <see cref="Out"/> (0.5 to 1).</summary>
  460. /// <remarks><see href="https://easings.net/#easeInOutCubic">Easings.net has a graph of this function.</see></remarks>
  461. public static float InOut(float value)
  462. {
  463. value *= 2;
  464. if (value <= 1)
  465. {
  466. return 0.5f * value * value * value;
  467. }
  468. else
  469. {
  470. value -= 2;
  471. return 0.5f * (value * value * value + 2);
  472. }
  473. }
  474. /************************************************************************************************************************/
  475. /// <summary>Returns the derivative of <see cref="In(float)"/> (<c>y = 3x</c>).</summary>
  476. public static float InDerivative(float value) => 3 * value * value;
  477. /// <summary>Returns the derivative of <see cref="Out(float)"/> (<c>y = 3 * (x - 1)</c>).</summary>
  478. public static float OutDerivative(float value)
  479. {
  480. value--;
  481. return 3 * value * value;
  482. }
  483. /// <summary>Returns the derivative of <see cref="InOut(float)"/>.</summary>
  484. public static float InOutDerivative(float value)
  485. {
  486. value *= 2;
  487. if (value <= 1)
  488. {
  489. return 3 * value * value;
  490. }
  491. else
  492. {
  493. value -= 2;
  494. return 3 * value * value;
  495. }
  496. }
  497. /************************************************************************************************************************/
  498. // Ranged Variants.
  499. /************************************************************************************************************************/
  500. /// <summary>A variant of <see cref="In(float)"/> with a custom range instead of 0 to 1.</summary>
  501. public static float In(float start, float end, float value) => Lerp(start, end, In(UnLerp(start, end, value)));
  502. /// <summary>A variant of <see cref="Out(float)"/> with a custom range instead of 0 to 1.</summary>
  503. public static float Out(float start, float end, float value) => Lerp(start, end, Out(UnLerp(start, end, value)));
  504. /// <summary>A variant of <see cref="InOut(float)"/> with a custom range instead of 0 to 1.</summary>
  505. public static float InOut(float start, float end, float value) => Lerp(start, end, InOut(UnLerp(start, end, value)));
  506. /// <summary>A variant of <see cref="InDerivative(float)"/> with a custom range instead of 0 to 1.</summary>
  507. public static float InDerivative(float start, float end, float value) => InDerivative(UnLerp(start, end, value)) * (end - start);
  508. /// <summary>A variant of <see cref="InDerivative(float)"/> with a custom range instead of 0 to 1.</summary>
  509. public static float OutDerivative(float start, float end, float value) => OutDerivative(UnLerp(start, end, value)) * (end - start);
  510. /// <summary>A variant of <see cref="InDerivative(float)"/> with a custom range instead of 0 to 1.</summary>
  511. public static float InOutDerivative(float start, float end, float value) => InOutDerivative(UnLerp(start, end, value)) * (end - start);
  512. /************************************************************************************************************************/
  513. }
  514. /************************************************************************************************************************/
  515. #endregion
  516. /************************************************************************************************************************/
  517. #region Quartic
  518. /************************************************************************************************************************/
  519. /// <summary>Functions based on quartic equations (<c>x^4</c>).</summary>
  520. /// https://kybernetik.com.au/animancer/api/Animancer/Quartic
  521. ///
  522. public static class Quartic
  523. {
  524. /************************************************************************************************************************/
  525. /// <summary>Interpolates the `value` based on the line <c>y = x^4</c>.</summary>
  526. /// <remarks><see href="https://easings.net/#easeInQuart">Easings.net has a graph of this function.</see></remarks>
  527. public static float In(float value) => value * value * value * value;
  528. /// <summary>Interpolates the `value` based on the line <c>y = 1 - (x - 1)^4</c>.</summary>
  529. /// <remarks><see href="https://easings.net/#easeOutQuart">Easings.net has a graph of this function.</see></remarks>
  530. public static float Out(float value)
  531. {
  532. value--;
  533. return -value * value * value * value + 1;
  534. }
  535. /// <summary>Interpolate using <see cref="In"/> (0 to 0.5) or <see cref="Out"/> (0.5 to 1).</summary>
  536. /// <remarks><see href="https://easings.net/#easeInOutQuart">Easings.net has a graph of this function.</see></remarks>
  537. public static float InOut(float value)
  538. {
  539. value *= 2;
  540. if (value <= 1)
  541. {
  542. return 0.5f * value * value * value * value;
  543. }
  544. else
  545. {
  546. value -= 2;
  547. return 0.5f * (-value * value * value * value + 2);
  548. }
  549. }
  550. /************************************************************************************************************************/
  551. /// <summary>Returns the derivative of <see cref="In(float)"/> (<c>y = 4x</c>).</summary>
  552. public static float InDerivative(float value) => 4 * value * value * value;
  553. /// <summary>Returns the derivative of <see cref="Out(float)"/> (<c>y = -4 * (x - 1)</c>).</summary>
  554. public static float OutDerivative(float value)
  555. {
  556. value--;
  557. return -4 * value * value * value;
  558. }
  559. /// <summary>Returns the derivative of <see cref="InOut(float)"/>.</summary>
  560. public static float InOutDerivative(float value)
  561. {
  562. value *= 2;
  563. if (value <= 1)
  564. {
  565. return 4 * value * value * value;
  566. }
  567. else
  568. {
  569. value -= 2;
  570. return -4 * value * value * value;
  571. }
  572. }
  573. /************************************************************************************************************************/
  574. // Ranged Variants.
  575. /************************************************************************************************************************/
  576. /// <summary>A variant of <see cref="In(float)"/> with a custom range instead of 0 to 1.</summary>
  577. public static float In(float start, float end, float value) => Lerp(start, end, In(UnLerp(start, end, value)));
  578. /// <summary>A variant of <see cref="Out(float)"/> with a custom range instead of 0 to 1.</summary>
  579. public static float Out(float start, float end, float value) => Lerp(start, end, Out(UnLerp(start, end, value)));
  580. /// <summary>A variant of <see cref="InOut(float)"/> with a custom range instead of 0 to 1.</summary>
  581. public static float InOut(float start, float end, float value) => Lerp(start, end, InOut(UnLerp(start, end, value)));
  582. /// <summary>A variant of <see cref="InDerivative(float)"/> with a custom range instead of 0 to 1.</summary>
  583. public static float InDerivative(float start, float end, float value) => InDerivative(UnLerp(start, end, value)) * (end - start);
  584. /// <summary>A variant of <see cref="InDerivative(float)"/> with a custom range instead of 0 to 1.</summary>
  585. public static float OutDerivative(float start, float end, float value) => OutDerivative(UnLerp(start, end, value)) * (end - start);
  586. /// <summary>A variant of <see cref="InDerivative(float)"/> with a custom range instead of 0 to 1.</summary>
  587. public static float InOutDerivative(float start, float end, float value) => InOutDerivative(UnLerp(start, end, value)) * (end - start);
  588. /************************************************************************************************************************/
  589. }
  590. /************************************************************************************************************************/
  591. #endregion
  592. /************************************************************************************************************************/
  593. #region Quintic
  594. /************************************************************************************************************************/
  595. /// <summary>Functions based on quintic equations (<c>x^5</c>).</summary>
  596. /// https://kybernetik.com.au/animancer/api/Animancer/Quintic
  597. ///
  598. public static class Quintic
  599. {
  600. /************************************************************************************************************************/
  601. /// <summary>Interpolates the `value` based on the line <c>y = x^5</c>.</summary>
  602. /// <remarks><see href="https://easings.net/#easeInQuint">Easings.net has a graph of this function.</see></remarks>
  603. public static float In(float value) => value * value * value * value * value;
  604. /// <summary>Interpolates the `value` based on the line <c>y = 1 + (x - 1)^5</c>.</summary>
  605. /// <remarks><see href="https://easings.net/#easeOutQuint">Easings.net has a graph of this function.</see></remarks>
  606. public static float Out(float value)
  607. {
  608. value--;
  609. return value * value * value * value * value + 1;
  610. }
  611. /// <summary>Interpolate using <see cref="In"/> (0 to 0.5) or <see cref="Out"/> (0.5 to 1).</summary>
  612. /// <remarks><see href="https://easings.net/#easeInOutQuint">Easings.net has a graph of this function.</see></remarks>
  613. public static float InOut(float value)
  614. {
  615. value *= 2;
  616. if (value <= 1)
  617. {
  618. return 0.5f * value * value * value * value * value;
  619. }
  620. else
  621. {
  622. value -= 2;
  623. return 0.5f * (value * value * value * value * value + 2);
  624. }
  625. }
  626. /************************************************************************************************************************/
  627. /// <summary>Returns the derivative of <see cref="In(float)"/> (<c>y = 5x</c>).</summary>
  628. public static float InDerivative(float value) => 5 * value * value * value * value;
  629. /// <summary>Returns the derivative of <see cref="Out(float)"/> (<c>y = -5 * (x - 1)</c>).</summary>
  630. public static float OutDerivative(float value)
  631. {
  632. value--;
  633. return 5 * value * value * value * value;
  634. }
  635. /// <summary>Returns the derivative of <see cref="InOut(float)"/>.</summary>
  636. public static float InOutDerivative(float value)
  637. {
  638. value *= 2;
  639. if (value <= 1)
  640. {
  641. return 5 * value * value * value * value;
  642. }
  643. else
  644. {
  645. value -= 2;
  646. return 5 * value * value * value * value;
  647. }
  648. }
  649. /************************************************************************************************************************/
  650. // Ranged Variants.
  651. /************************************************************************************************************************/
  652. /// <summary>A variant of <see cref="In(float)"/> with a custom range instead of 0 to 1.</summary>
  653. public static float In(float start, float end, float value) => Lerp(start, end, In(UnLerp(start, end, value)));
  654. /// <summary>A variant of <see cref="Out(float)"/> with a custom range instead of 0 to 1.</summary>
  655. public static float Out(float start, float end, float value) => Lerp(start, end, Out(UnLerp(start, end, value)));
  656. /// <summary>A variant of <see cref="InOut(float)"/> with a custom range instead of 0 to 1.</summary>
  657. public static float InOut(float start, float end, float value) => Lerp(start, end, InOut(UnLerp(start, end, value)));
  658. /// <summary>A variant of <see cref="InDerivative(float)"/> with a custom range instead of 0 to 1.</summary>
  659. public static float InDerivative(float start, float end, float value) => InDerivative(UnLerp(start, end, value)) * (end - start);
  660. /// <summary>A variant of <see cref="InDerivative(float)"/> with a custom range instead of 0 to 1.</summary>
  661. public static float OutDerivative(float start, float end, float value) => OutDerivative(UnLerp(start, end, value)) * (end - start);
  662. /// <summary>A variant of <see cref="InDerivative(float)"/> with a custom range instead of 0 to 1.</summary>
  663. public static float InOutDerivative(float start, float end, float value) => InOutDerivative(UnLerp(start, end, value)) * (end - start);
  664. /************************************************************************************************************************/
  665. }
  666. /************************************************************************************************************************/
  667. #endregion
  668. /************************************************************************************************************************/
  669. #region Sine
  670. /************************************************************************************************************************/
  671. /// <summary>Functions based on sinusoidal equations.</summary>
  672. /// https://kybernetik.com.au/animancer/api/Animancer/Sine
  673. ///
  674. public static class Sine
  675. {
  676. /************************************************************************************************************************/
  677. /// <summary>Interpolates the `value` based on a quarter-cycle of a sine wave.</summary>
  678. /// <remarks><see href="https://easings.net/#easeInSine">Easings.net has a graph of this function.</see></remarks>
  679. public static float In(float value) => -Cos(value * (PI * 0.5f)) + 1;
  680. /// <summary>Interpolates the `value` based on a quarter-cycle of a sine wave.</summary>
  681. /// <remarks><see href="https://easings.net/#easeOutSine">Easings.net has a graph of this function.</see></remarks>
  682. public static float Out(float value) => Sin(value * (PI * 0.5f));
  683. /// <summary>Interpolate using <see cref="In"/> (0 to 0.5) or <see cref="Out"/> (0.5 to 1).</summary>
  684. /// <remarks><see href="https://easings.net/#easeInOutSine">Easings.net has a graph of this function.</see></remarks>
  685. public static float InOut(float value) => -0.5f * (Cos(PI * value) - 1);
  686. /************************************************************************************************************************/
  687. /// <summary>Returns the derivative of <see cref="In(float)"/>.</summary>
  688. public static float InDerivative(float value) => 0.5f * PI * Sin(0.5f * PI * value);
  689. /// <summary>Returns the derivative of <see cref="Out(float)"/>.</summary>
  690. public static float OutDerivative(float value) => PI * 0.5f * Cos(value * (PI * 0.5f));
  691. /// <summary>Returns the derivative of <see cref="InOut(float)"/>.</summary>
  692. public static float InOutDerivative(float value) => 0.5f * PI * Sin(PI * value);
  693. /************************************************************************************************************************/
  694. // Ranged Variants.
  695. /************************************************************************************************************************/
  696. /// <summary>A variant of <see cref="In(float)"/> with a custom range instead of 0 to 1.</summary>
  697. public static float In(float start, float end, float value) => Lerp(start, end, In(UnLerp(start, end, value)));
  698. /// <summary>A variant of <see cref="Out(float)"/> with a custom range instead of 0 to 1.</summary>
  699. public static float Out(float start, float end, float value) => Lerp(start, end, Out(UnLerp(start, end, value)));
  700. /// <summary>A variant of <see cref="InOut(float)"/> with a custom range instead of 0 to 1.</summary>
  701. public static float InOut(float start, float end, float value) => Lerp(start, end, InOut(UnLerp(start, end, value)));
  702. /// <summary>A variant of <see cref="InDerivative(float)"/> with a custom range instead of 0 to 1.</summary>
  703. public static float InDerivative(float start, float end, float value) => InDerivative(UnLerp(start, end, value)) * (end - start);
  704. /// <summary>A variant of <see cref="InDerivative(float)"/> with a custom range instead of 0 to 1.</summary>
  705. public static float OutDerivative(float start, float end, float value) => OutDerivative(UnLerp(start, end, value)) * (end - start);
  706. /// <summary>A variant of <see cref="InDerivative(float)"/> with a custom range instead of 0 to 1.</summary>
  707. public static float InOutDerivative(float start, float end, float value) => InOutDerivative(UnLerp(start, end, value)) * (end - start);
  708. /************************************************************************************************************************/
  709. }
  710. /************************************************************************************************************************/
  711. #endregion
  712. /************************************************************************************************************************/
  713. #region Exponential
  714. /************************************************************************************************************************/
  715. /// <summary>Functions based on exponential equations (<c>2^(10(x))</c>).</summary>
  716. /// https://kybernetik.com.au/animancer/api/Animancer/Exponential
  717. ///
  718. public static class Exponential
  719. {
  720. /************************************************************************************************************************/
  721. /// <summary>Interpolates the `value` based on the line (<c>y = 2^(10 * (x - 1))</c>).</summary>
  722. /// <remarks><see href="https://easings.net/#easeInExpo">Easings.net has a graph of this function.</see></remarks>
  723. public static float In(float value) => Pow(2, 10 * (value - 1));
  724. /// <summary>Interpolates the `value` based on the line (<c>y = -2^(-10x) + 1</c>).</summary>
  725. /// <remarks><see href="https://easings.net/#easeOutExpo">Easings.net has a graph of this function.</see></remarks>
  726. public static float Out(float value) => -Pow(2, -10 * value) + 1;
  727. /// <summary>Interpolate using <see cref="In"/> (0 to 0.5) or <see cref="Out"/> (0.5 to 1).</summary>
  728. /// <remarks><see href="https://easings.net/#easeInOutExpo">Easings.net has a graph of this function.</see></remarks>
  729. public static float InOut(float value)
  730. {
  731. value *= 2;
  732. if (value <= 1)
  733. {
  734. return 0.5f * Pow(2, 10 * (value - 1));
  735. }
  736. else
  737. {
  738. value--;
  739. return 0.5f * (-Pow(2, -10 * value) + 2);
  740. }
  741. }
  742. /************************************************************************************************************************/
  743. /// <summary>Returns the derivative of <see cref="In(float)"/> (<c>y = 10 * ln(2) * 2^(10 * (x - 1))</c>).</summary>
  744. public static float InDerivative(float value) => 10 * Ln2 * Pow(2, 10 * (value - 1));
  745. /// <summary>Returns the derivative of <see cref="Out(float)"/> (<c>y = 5 * ln(2) * 2^(-10 * (x - 1) + 1)</c>).</summary>
  746. public static float OutDerivative(float value) => 5 * Ln2 * Pow(2, 1 - 10 * value);
  747. /// <summary>Returns the derivative of <see cref="InOut(float)"/>.</summary>
  748. public static float InOutDerivative(float value)
  749. {
  750. value *= 2;
  751. if (value <= 1)
  752. {
  753. return 10 * Ln2 * Pow(2, 10 * (value - 1));
  754. }
  755. else
  756. {
  757. value--;
  758. return 5 * Ln2 * Pow(2, 1 - 10 * value);
  759. }
  760. }
  761. /************************************************************************************************************************/
  762. // Ranged Variants.
  763. /************************************************************************************************************************/
  764. /// <summary>A variant of <see cref="In(float)"/> with a custom range instead of 0 to 1.</summary>
  765. public static float In(float start, float end, float value) => Lerp(start, end, In(UnLerp(start, end, value)));
  766. /// <summary>A variant of <see cref="Out(float)"/> with a custom range instead of 0 to 1.</summary>
  767. public static float Out(float start, float end, float value) => Lerp(start, end, Out(UnLerp(start, end, value)));
  768. /// <summary>A variant of <see cref="InOut(float)"/> with a custom range instead of 0 to 1.</summary>
  769. public static float InOut(float start, float end, float value) => Lerp(start, end, InOut(UnLerp(start, end, value)));
  770. /// <summary>A variant of <see cref="InDerivative(float)"/> with a custom range instead of 0 to 1.</summary>
  771. public static float InDerivative(float start, float end, float value) => InDerivative(UnLerp(start, end, value)) * (end - start);
  772. /// <summary>A variant of <see cref="InDerivative(float)"/> with a custom range instead of 0 to 1.</summary>
  773. public static float OutDerivative(float start, float end, float value) => OutDerivative(UnLerp(start, end, value)) * (end - start);
  774. /// <summary>A variant of <see cref="InDerivative(float)"/> with a custom range instead of 0 to 1.</summary>
  775. public static float InOutDerivative(float start, float end, float value) => InOutDerivative(UnLerp(start, end, value)) * (end - start);
  776. /************************************************************************************************************************/
  777. }
  778. /************************************************************************************************************************/
  779. #endregion
  780. /************************************************************************************************************************/
  781. #region Circular
  782. /************************************************************************************************************************/
  783. /// <summary>Functions based on circular equations.</summary>
  784. /// https://kybernetik.com.au/animancer/api/Animancer/Circular
  785. ///
  786. public static class Circular
  787. {
  788. /************************************************************************************************************************/
  789. /// <summary>Interpolates the `value` based on a shifted quadrant IV of a unit circle.</summary>
  790. /// <remarks><see href="https://easings.net/#easeInCirc">Easings.net has a graph of this function.</see></remarks>
  791. public static float In(float value) => -(Sqrt(1 - value * value) - 1);
  792. /// <summary>Interpolates the `value` based on a shifted quadrant II of a unit circle.</summary>
  793. /// <remarks><see href="https://easings.net/#easeOutCirc">Easings.net has a graph of this function.</see></remarks>
  794. public static float Out(float value)
  795. {
  796. value--;
  797. return Sqrt(1 - value * value);
  798. }
  799. /// <summary>Interpolate using <see cref="In"/> (0 to 0.5) or <see cref="Out"/> (0.5 to 1).</summary>
  800. /// <remarks><see href="https://easings.net/#easeInOutCirc">Easings.net has a graph of this function.</see></remarks>
  801. public static float InOut(float value)
  802. {
  803. value *= 2;
  804. if (value <= 1)
  805. {
  806. return -0.5f * (Sqrt(1 - value * value) - 1);
  807. }
  808. else
  809. {
  810. value -= 2;
  811. return 0.5f * (Sqrt(1 - value * value) + 1);
  812. }
  813. }
  814. /************************************************************************************************************************/
  815. /// <summary>Returns the derivative of <see cref="In(float)"/>.</summary>
  816. public static float InDerivative(float value) => value / Sqrt(1 - value * value);
  817. /// <summary>Returns the derivative of <see cref="Out(float)"/>.</summary>
  818. public static float OutDerivative(float value)
  819. {
  820. value--;
  821. return -value / Sqrt(1 - value * value);
  822. }
  823. /// <summary>Returns the derivative of <see cref="InOut(float)"/>.</summary>
  824. public static float InOutDerivative(float value)
  825. {
  826. value *= 2;
  827. if (value <= 1)
  828. {
  829. return value / (2 * Sqrt(1 - value * value));
  830. }
  831. else
  832. {
  833. value -= 2;
  834. return -value / (2 * Sqrt(1 - value * value));
  835. }
  836. }
  837. /************************************************************************************************************************/
  838. // Ranged Variants.
  839. /************************************************************************************************************************/
  840. /// <summary>A variant of <see cref="In(float)"/> with a custom range instead of 0 to 1.</summary>
  841. public static float In(float start, float end, float value) => Lerp(start, end, In(UnLerp(start, end, value)));
  842. /// <summary>A variant of <see cref="Out(float)"/> with a custom range instead of 0 to 1.</summary>
  843. public static float Out(float start, float end, float value) => Lerp(start, end, Out(UnLerp(start, end, value)));
  844. /// <summary>A variant of <see cref="InOut(float)"/> with a custom range instead of 0 to 1.</summary>
  845. public static float InOut(float start, float end, float value) => Lerp(start, end, InOut(UnLerp(start, end, value)));
  846. /// <summary>A variant of <see cref="InDerivative(float)"/> with a custom range instead of 0 to 1.</summary>
  847. public static float InDerivative(float start, float end, float value) => InDerivative(UnLerp(start, end, value)) * (end - start);
  848. /// <summary>A variant of <see cref="InDerivative(float)"/> with a custom range instead of 0 to 1.</summary>
  849. public static float OutDerivative(float start, float end, float value) => OutDerivative(UnLerp(start, end, value)) * (end - start);
  850. /// <summary>A variant of <see cref="InDerivative(float)"/> with a custom range instead of 0 to 1.</summary>
  851. public static float InOutDerivative(float start, float end, float value) => InOutDerivative(UnLerp(start, end, value)) * (end - start);
  852. /************************************************************************************************************************/
  853. }
  854. /************************************************************************************************************************/
  855. #endregion
  856. /************************************************************************************************************************/
  857. #region Back
  858. /************************************************************************************************************************/
  859. /// <summary>Functions based on equations which go out of bounds then come back.</summary>
  860. /// https://kybernetik.com.au/animancer/api/Animancer/Back
  861. ///
  862. public static class Back
  863. {
  864. /************************************************************************************************************************/
  865. private const float C = 1.758f;
  866. /************************************************************************************************************************/
  867. /// <remarks><see href="https://easings.net/#easeInBack">Easings.net has a graph of this function.</see></remarks>
  868. public static float In(float value) => value * value * ((C + 1) * value - C);
  869. /// <remarks><see href="https://easings.net/#easeOutBack">Easings.net has a graph of this function.</see></remarks>
  870. public static float Out(float value)
  871. {
  872. value -= 1;
  873. return value * value * ((C + 1) * value + C) + 1;
  874. }
  875. /// <summary>Interpolate using <see cref="In"/> (0 to 0.5) or <see cref="Out"/> (0.5 to 1).</summary>
  876. /// <remarks><see href="https://easings.net/#easeInOutBack">Easings.net has a graph of this function.</see></remarks>
  877. public static float InOut(float value)
  878. {
  879. value *= 2;
  880. if (value <= 1)
  881. {
  882. return 0.5f * value * value * ((C + 1) * value - C);
  883. }
  884. else
  885. {
  886. value -= 2;
  887. return 0.5f * (value * value * ((C + 1) * value + C) + 2);
  888. }
  889. }
  890. /************************************************************************************************************************/
  891. /// <summary>Returns the derivative of <see cref="In(float)"/>.</summary>
  892. public static float InDerivative(float value) => 3 * (C + 1) * value * value - 2 * C * value;
  893. /// <summary>Returns the derivative of <see cref="Out(float)"/>.</summary>
  894. public static float OutDerivative(float value)
  895. {
  896. value -= 1;
  897. return (C + 1) * value * value + 2 * value * ((C + 1) * value + C);
  898. }
  899. /// <summary>Returns the derivative of <see cref="InOut(float)"/>.</summary>
  900. public static float InOutDerivative(float value)
  901. {
  902. value *= 2;
  903. if (value <= 1)
  904. {
  905. return 3 * (C + 1) * value * value - 2 * C * value;
  906. }
  907. else
  908. {
  909. value -= 2;
  910. return (C + 1) * value * value + 2 * value * ((C + 1) * value + C);
  911. }
  912. }
  913. /************************************************************************************************************************/
  914. // Ranged Variants.
  915. /************************************************************************************************************************/
  916. /// <summary>A variant of <see cref="In(float)"/> with a custom range instead of 0 to 1.</summary>
  917. public static float In(float start, float end, float value) => Lerp(start, end, In(UnLerp(start, end, value)));
  918. /// <summary>A variant of <see cref="Out(float)"/> with a custom range instead of 0 to 1.</summary>
  919. public static float Out(float start, float end, float value) => Lerp(start, end, Out(UnLerp(start, end, value)));
  920. /// <summary>A variant of <see cref="InOut(float)"/> with a custom range instead of 0 to 1.</summary>
  921. public static float InOut(float start, float end, float value) => Lerp(start, end, InOut(UnLerp(start, end, value)));
  922. /// <summary>A variant of <see cref="InDerivative(float)"/> with a custom range instead of 0 to 1.</summary>
  923. public static float InDerivative(float start, float end, float value) => InDerivative(UnLerp(start, end, value)) * (end - start);
  924. /// <summary>A variant of <see cref="InDerivative(float)"/> with a custom range instead of 0 to 1.</summary>
  925. public static float OutDerivative(float start, float end, float value) => OutDerivative(UnLerp(start, end, value)) * (end - start);
  926. /// <summary>A variant of <see cref="InDerivative(float)"/> with a custom range instead of 0 to 1.</summary>
  927. public static float InOutDerivative(float start, float end, float value) => InOutDerivative(UnLerp(start, end, value)) * (end - start);
  928. /************************************************************************************************************************/
  929. }
  930. /************************************************************************************************************************/
  931. #endregion
  932. /************************************************************************************************************************/
  933. #region Bounce
  934. /************************************************************************************************************************/
  935. /// <summary>Functions based on equations with sharp bounces.</summary>
  936. /// https://kybernetik.com.au/animancer/api/Animancer/Bounce
  937. ///
  938. public static class Bounce
  939. {
  940. /************************************************************************************************************************/
  941. /// <remarks><see href="https://easings.net/#easeInBounce">Easings.net has a graph of this function.</see></remarks>
  942. public static float In(float value)
  943. {
  944. return 1 - Out(1 - value);
  945. }
  946. /// <remarks><see href="https://easings.net/#easeOutBounce">Easings.net has a graph of this function.</see></remarks>
  947. public static float Out(float value)
  948. {
  949. switch (value)
  950. {
  951. case 0: return 0;
  952. case 1: return 1;
  953. }
  954. if (value < (1f / 2.75f))
  955. {
  956. return 7.5625f * value * value;
  957. }
  958. else if (value < (2f / 2.75f))
  959. {
  960. value -= 1.5f / 2.75f;
  961. return 7.5625f * value * value + 0.75f;
  962. }
  963. else if (value < (2.5f / 2.75f))
  964. {
  965. value -= 2.25f / 2.75f;
  966. return 7.5625f * value * value + 0.9375f;
  967. }
  968. else
  969. {
  970. value -= 2.625f / 2.75f;
  971. return 7.5625f * value * value + 0.984375f;
  972. }
  973. }
  974. /// <summary>Interpolate using <see cref="In"/> (0 to 0.5) or <see cref="Out"/> (0.5 to 1).</summary>
  975. /// <remarks><see href="https://easings.net/#easeInOutBounce">Easings.net has a graph of this function.</see></remarks>
  976. public static float InOut(float value)
  977. {
  978. if (value < 0.5f)
  979. return 0.5f * In(value * 2);
  980. else
  981. return 0.5f + 0.5f * Out(value * 2 - 1);
  982. }
  983. /************************************************************************************************************************/
  984. /// <summary>Returns the derivative of <see cref="In(float)"/>.</summary>
  985. public static float InDerivative(float value) => OutDerivative(1 - value);
  986. /// <summary>Returns the derivative of <see cref="Out(float)"/>.</summary>
  987. public static float OutDerivative(float value)
  988. {
  989. if (value < (1f / 2.75f))
  990. {
  991. return 2 * 7.5625f * value;
  992. }
  993. else if (value < (2f / 2.75f))
  994. {
  995. value -= 1.5f / 2.75f;
  996. return 2 * 7.5625f * value;
  997. }
  998. else if (value < (2.5f / 2.75f))
  999. {
  1000. value -= 2.25f / 2.75f;
  1001. return 2 * 7.5625f * value;
  1002. }
  1003. else
  1004. {
  1005. value -= 2.625f / 2.75f;
  1006. return 2 * 7.5625f * value;
  1007. }
  1008. }
  1009. /// <summary>Returns the derivative of <see cref="InOut(float)"/>.</summary>
  1010. public static float InOutDerivative(float value)
  1011. {
  1012. value *= 2;
  1013. if (value <= 1)
  1014. return OutDerivative(1 - value);
  1015. else
  1016. return OutDerivative(value - 1);
  1017. }
  1018. /************************************************************************************************************************/
  1019. // Ranged Variants.
  1020. /************************************************************************************************************************/
  1021. /// <summary>A variant of <see cref="In(float)"/> with a custom range instead of 0 to 1.</summary>
  1022. public static float In(float start, float end, float value) => Lerp(start, end, In(UnLerp(start, end, value)));
  1023. /// <summary>A variant of <see cref="Out(float)"/> with a custom range instead of 0 to 1.</summary>
  1024. public static float Out(float start, float end, float value) => Lerp(start, end, Out(UnLerp(start, end, value)));
  1025. /// <summary>A variant of <see cref="InOut(float)"/> with a custom range instead of 0 to 1.</summary>
  1026. public static float InOut(float start, float end, float value) => Lerp(start, end, InOut(UnLerp(start, end, value)));
  1027. /// <summary>A variant of <see cref="InDerivative(float)"/> with a custom range instead of 0 to 1.</summary>
  1028. public static float InDerivative(float start, float end, float value) => InDerivative(UnLerp(start, end, value)) * (end - start);
  1029. /// <summary>A variant of <see cref="InDerivative(float)"/> with a custom range instead of 0 to 1.</summary>
  1030. public static float OutDerivative(float start, float end, float value) => OutDerivative(UnLerp(start, end, value)) * (end - start);
  1031. /// <summary>A variant of <see cref="InDerivative(float)"/> with a custom range instead of 0 to 1.</summary>
  1032. public static float InOutDerivative(float start, float end, float value) => InOutDerivative(UnLerp(start, end, value)) * (end - start);
  1033. /************************************************************************************************************************/
  1034. }
  1035. /************************************************************************************************************************/
  1036. #endregion
  1037. /************************************************************************************************************************/
  1038. #region Elastic
  1039. /************************************************************************************************************************/
  1040. /// <summary>Functions based on equations with soft bounces.</summary>
  1041. /// https://kybernetik.com.au/animancer/api/Animancer/Elastic
  1042. ///
  1043. public static class Elastic
  1044. {
  1045. /************************************************************************************************************************/
  1046. /// <summary><c>2 / 3 * pi</c></summary>
  1047. public const float TwoThirdsPi = 2f / 3f * PI;
  1048. /************************************************************************************************************************/
  1049. /// <remarks><see href="https://easings.net/#easeInElastic">Easings.net has a graph of this function.</see></remarks>
  1050. public static float In(float value)
  1051. {
  1052. return value switch
  1053. {
  1054. 0 => 0,
  1055. 1 => 1,
  1056. _ => -Pow(2, 10 * value - 10) * Sin((value * 10 - 10.75f) * TwoThirdsPi),
  1057. };
  1058. }
  1059. /// <remarks><see href="https://easings.net/#easeOutElastic">Easings.net has a graph of this function.</see></remarks>
  1060. public static float Out(float value)
  1061. {
  1062. return value switch
  1063. {
  1064. 0 => 0,
  1065. 1 => 1,
  1066. _ => 1 + Pow(2, -10 * value) * Sin((value * -10 - 0.75f) * TwoThirdsPi),
  1067. };
  1068. }
  1069. /// <summary>Interpolate using <see cref="In"/> (0 to 0.5) or <see cref="Out"/> (0.5 to 1).</summary>
  1070. /// <remarks><see href="https://easings.net/#easeInOutElastic">Easings.net has a graph of this function.</see></remarks>
  1071. public static float InOut(float value)
  1072. {
  1073. switch (value)
  1074. {
  1075. case 0: return 0;
  1076. case 0.5f: return 0.5f;
  1077. case 1: return 1;
  1078. }
  1079. value *= 2;
  1080. if (value <= 1)
  1081. {
  1082. return 0.5f * (-Pow(2, 10 * value - 10) * Sin((value * 10 - 10.75f) * TwoThirdsPi));
  1083. }
  1084. else
  1085. {
  1086. value--;
  1087. return 0.5f + 0.5f * (1 + Pow(2, -10 * value) * Sin((value * -10 - 0.75f) * TwoThirdsPi));
  1088. }
  1089. }
  1090. /************************************************************************************************************************/
  1091. /// <summary>Returns the derivative of <see cref="In(float)"/>.</summary>
  1092. public static float InDerivative(float value)
  1093. {
  1094. return -(5 * Pow(2, 10 * value - 9) *
  1095. (3 * Ln2 * Sin(PI * (40 * value - 43) / 6) +
  1096. 2 * PI * Cos(PI * (40 * value - 43) / 6))) / 3;
  1097. }
  1098. /// <summary>Returns the derivative of <see cref="Out(float)"/>.</summary>
  1099. public static float OutDerivative(float value)
  1100. {
  1101. return -(30 * Ln2 * Sin(2 * PI * (10 * value - 3f / 4f) / 3) -
  1102. 20 * PI * Cos(2 * PI * (10 * value - 3f / 4f) / 3)) /
  1103. (3 * Pow(2, 10 * value));
  1104. }
  1105. /// <summary>Returns the derivative of <see cref="InOut(float)"/>.</summary>
  1106. public static float InOutDerivative(float value)
  1107. {
  1108. value *= 2;
  1109. if (value <= 1)
  1110. return OutDerivative(1 - value);
  1111. else
  1112. return OutDerivative(value - 1);
  1113. }
  1114. /************************************************************************************************************************/
  1115. // Ranged Variants.
  1116. /************************************************************************************************************************/
  1117. /// <summary>A variant of <see cref="In(float)"/> with a custom range instead of 0 to 1.</summary>
  1118. public static float In(float start, float end, float value) => Lerp(start, end, In(UnLerp(start, end, value)));
  1119. /// <summary>A variant of <see cref="Out(float)"/> with a custom range instead of 0 to 1.</summary>
  1120. public static float Out(float start, float end, float value) => Lerp(start, end, Out(UnLerp(start, end, value)));
  1121. /// <summary>A variant of <see cref="InOut(float)"/> with a custom range instead of 0 to 1.</summary>
  1122. public static float InOut(float start, float end, float value) => Lerp(start, end, InOut(UnLerp(start, end, value)));
  1123. /// <summary>A variant of <see cref="InDerivative(float)"/> with a custom range instead of 0 to 1.</summary>
  1124. public static float InDerivative(float start, float end, float value) => InDerivative(UnLerp(start, end, value)) * (end - start);
  1125. /// <summary>A variant of <see cref="InDerivative(float)"/> with a custom range instead of 0 to 1.</summary>
  1126. public static float OutDerivative(float start, float end, float value) => OutDerivative(UnLerp(start, end, value)) * (end - start);
  1127. /// <summary>A variant of <see cref="InDerivative(float)"/> with a custom range instead of 0 to 1.</summary>
  1128. public static float InOutDerivative(float start, float end, float value) => InOutDerivative(UnLerp(start, end, value)) * (end - start);
  1129. /************************************************************************************************************************/
  1130. }
  1131. /************************************************************************************************************************/
  1132. #endregion
  1133. /************************************************************************************************************************/
  1134. }
  1135. }