Mathfx
m (→Usage: Made the formatting less weird) |
|||
Line 8: | Line 8: | ||
== Usage == | == Usage == | ||
* '''Hermite''' - This method will interpolate while easing in and out at the limits. | * '''Hermite''' - This method will interpolate while easing in and out at the limits. | ||
− | + | :[[Image:Mathfx-Hermite.png|Graph of the Hermite function.]] | |
* '''Sinerp''' - Short for 'sinusoidal interpolation', this method will interpolate while easing around the end, when value is near one. | * '''Sinerp''' - Short for 'sinusoidal interpolation', this method will interpolate while easing around the end, when value is near one. | ||
− | + | :[[Image:Mathfx-Sinerp.png|Graph of the Sinerp function.]] | |
* '''Berp''' - Short for 'boing-like interpolation', this method will first overshoot, then waver back and forth around the end value before coming to a rest. | * '''Berp''' - Short for 'boing-like interpolation', this method will first overshoot, then waver back and forth around the end value before coming to a rest. | ||
− | + | :[[Image:Mathfx-Berp.png|Graph of the Berp function.]] | |
* '''Bounce''' - Returns a value between 0 and 1 that can be used to easily make bouncing GUI items (a la OS X's Dock) | * '''Bounce''' - Returns a value between 0 and 1 that can be used to easily make bouncing GUI items (a la OS X's Dock) | ||
− | + | :[[Image:Mathfx-Bounce.png|Graph of the Bounce function.]] | |
* '''SmoothStep''' - Works like Lerp, but has ease-in and ease-out of the values. | * '''SmoothStep''' - Works like Lerp, but has ease-in and ease-out of the values. | ||
* '''Lerp''' - Short for 'linearly interpolate', this method is equivalent to Unity's Mathf.Lerp, included for comparison. | * '''Lerp''' - Short for 'linearly interpolate', this method is equivalent to Unity's Mathf.Lerp, included for comparison. | ||
− | + | :[[Image:Mathfx-Lerp.png|Graph of the Lerp function.]] | |
* '''NearestPoint''' - Will return the nearest point on a line to a point. Useful for making an object follow a track. | * '''NearestPoint''' - Will return the nearest point on a line to a point. Useful for making an object follow a track. | ||
* '''NearestPointStrict''' - Works like NearestPoint except the end of the line is clamped. | * '''NearestPointStrict''' - Works like NearestPoint except the end of the line is clamped. |
Revision as of 21:10, 20 February 2009
Contents |
Description
The following snippet provides short functions for floating point numbers. See the usage section for individualized information.
Usage
- Hermite - This method will interpolate while easing in and out at the limits.
- Sinerp - Short for 'sinusoidal interpolation', this method will interpolate while easing around the end, when value is near one.
- Berp - Short for 'boing-like interpolation', this method will first overshoot, then waver back and forth around the end value before coming to a rest.
- Bounce - Returns a value between 0 and 1 that can be used to easily make bouncing GUI items (a la OS X's Dock)
- SmoothStep - Works like Lerp, but has ease-in and ease-out of the values.
- Lerp - Short for 'linearly interpolate', this method is equivalent to Unity's Mathf.Lerp, included for comparison.
- NearestPoint - Will return the nearest point on a line to a point. Useful for making an object follow a track.
- NearestPointStrict - Works like NearestPoint except the end of the line is clamped.
History
- Added Approx function for testing float value within an offset range. All thanks to Opless for this!
- Clerp added by Jeff Craighead 10:51, 2 May 2008 (PDT)
- Added JavaScript conversion
C# - Mathfx.cs
<csharp> using UnityEngine; using System;
public class Mathfx {
public static float Hermite(float start, float end, float value) { return Mathf.Lerp(start, end, value * value * (3.0f - 2.0f * value)); } public static float Sinerp(float start, float end, float value) { return Mathf.Lerp(start, end, Mathf.Sin(value * Mathf.PI * 0.5f)); } public static float Berp(float start, float end, float value) { value = Mathf.Clamp01(value); value = (Mathf.Sin(value * Mathf.PI * (0.2f + 2.5f * value * value * value)) * Mathf.Pow(1f - value, 2.2f) + value) * (1f + (1.2f * (1f - value))); return start + (end - start) * value; } public static float SmoothStep (float x, float min, float max) { x = Mathf.Clamp (x, min, max); float v1 = (x-min)/(max-min); float v2 = (x-min)/(max-min); return -2*v1 * v1 *v1 + 3*v2 * v2; } public static float Lerp(float start, float end, float value) { return ((1.0f - value) * start) + (value * end); } public static Vector3 NearestPoint(Vector3 lineStart, Vector3 lineEnd, Vector3 point) { Vector3 lineDirection = Vector3.Normalize(lineEnd-lineStart); float closestPoint = Vector3.Dot((point-lineStart),lineDirection)/Vector3.Dot(lineDirection,lineDirection); return lineStart+(closestPoint*lineDirection); } public static Vector3 NearestPointStrict(Vector3 lineStart, Vector3 lineEnd, Vector3 point) { Vector3 fullDirection = lineEnd-lineStart; Vector3 lineDirection = Vector3.Normalize(fullDirection); float closestPoint = Vector3.Dot((point-lineStart),lineDirection)/Vector3.Dot(lineDirection,lineDirection); return lineStart+(Mathf.Clamp(closestPoint,0.0f,Vector3.Magnitude(fullDirection))*lineDirection); } public static float Bounce(float x) { return Mathf.Abs(Mathf.Sin(6.28f*(x+1f)*(x+1f)) * (1f-x)); } // test for value that is near specified float (due to floating point inprecision) // all thanks to Opless for this! public static bool Approx(float val, float about, float range) { return ( ( Mathf.Abs(val - about) < range) ); }
// test if a Vector3 is close to another Vector3 (due to floating point inprecision) // compares the square of the distance to the square of the range as this // avoids calculating a square root which is much slower than squaring the range public static bool Approx(Vector3 val, Vector3 about, float range) { return ( (val - about).sqrMagnitude < range*range); }
/* * CLerp - Circular Lerp - is like lerp but handles the wraparound from 0 to 360. * This is useful when interpolating eulerAngles and the object * crosses the 0/360 boundary. The standard Lerp function causes the object * to rotate in the wrong direction and looks stupid. Clerp fixes that. */ public static float Clerp(float start , float end, float value){ float min = 0.0f; float max = 360.0f; float half = Mathf.Abs((max - min)/2.0f);//half the distance between min and max float retval = 0.0f; float diff = 0.0f;
if((end - start) < -half){ diff = ((max - start)+end)*value;
retval = start+diff;
} else if((end - start) > half){ diff = -((max - end)+start)*value; retval = start+diff; } else retval = start+(end-start)*value;
// Debug.Log("Start: " + start + " End: " + end + " Value: " + value + " Half: " + half + " Diff: " + diff + " Retval: " + retval); return retval; }
} </csharp>
Js - Mathfx.js
I converted from the original C# format above. <javascript> // Put "import Mathfx;" at the top of the javascript you wish you use this code in
static function Hermite(start, end, value) {
return Mathf.Lerp(start, end, value * value * (3.0 - 2.0 * value));
}
static function Sinerp(start, end, value) {
return Mathf.Lerp(start, end, Mathf.Sin(value * Mathf.PI * 0.5));
}
static function Berp(start, end, value) {
value = Mathf.Clamp01(value); value = (Mathf.Sin(value * Mathf.PI * (0.2 + 2.5 * value * value * value)) * Mathf.Pow(1 - value, 2.2) + value) * (1 + (1.2 * (1 - value))); return start + (end - start) * value;
}
static function SmoothStep (x, min, max) {
x = Mathf.Clamp (x, min, max); var v1 = (x-min)/(max-min); var v2 = (x-min)/(max-min); return -2*v1 * v1 *v1 + 3*v2 * v2;
}
static function Lerp(start, end, value) {
return ((1.0 - value) * start) + (value * end);
}
static function NearestPoint(lineStart, lineEnd, point) {
var lineDirection = Vector3.Normalize(lineEnd-lineStart); var closestPoint = Vector3.Dot((point-lineStart),lineDirection)/Vector3.Dot(lineDirection,lineDirection); return lineStart+(closestPoint*lineDirection);
}
static function NearestPointStrict(lineStart, lineEnd, point) {
var fullDirection = lineEnd-lineStart; var lineDirection = Vector3.Normalize(fullDirection); var closestPoint = Vector3.Dot((point-lineStart),lineDirection)/Vector3.Dot(lineDirection,lineDirection); return lineStart+(Mathf.Clamp(closestPoint,0.0,Vector3.Magnitude(fullDirection))*lineDirection);
} static function Bounce(x) {
return Mathf.Abs(Mathf.Sin(6.28*(x+1)*(x+1)) * (1-x));
}
// test for value that is near specified float (due to floating point inprecision) // all thanks to Opless for this! static function Approx(val, about, range) {
return ( ( Mathf.Abs(val - about) < range) );
}
// test if a Vector3 is close to another Vector3 (due to floating point inprecision) // compares the square of the distance to the square of the range as this // avoids calculating a square root which is much slower than squaring the range static function Approx2(val, about, range) {
return ( (val - about).sqrMagnitude < range*range);
}
/*
- CLerp - Circular Lerp - is like lerp but handles the wraparound from 0 to 360.
- This is useful when interpolating eulerAngles and the object
- crosses the 0/360 boundary. The standard Lerp function causes the object
- to rotate in the wrong direction and looks stupid. Clerp fixes that.
- /
static function Clerp(start , end, value){
var min = 0.0; var max = 360.0; var half = Mathf.Abs((max - min)/2.0);//half the distance between min and max var retval = 0.0; var diff = 0.0;
if((end - start) < -half){ diff = ((max - start)+end)*value; retval = start+diff; } else if((end - start) > half){ diff = -((max - end)+start)*value; retval = start+diff; } else retval = start+(end-start)*value;
// Debug.Log("Start: " + start + " End: " + end + " Value: " + value + " Half: " + half + " Diff: " + diff + " Retval: " + retval); return retval;
} </javascript>