diff --git a/src/as/com/threerings/flash/MathUtil.as b/src/as/com/threerings/flash/MathUtil.as index 019a8c21..a57d857b 100644 --- a/src/as/com/threerings/flash/MathUtil.as +++ b/src/as/com/threerings/flash/MathUtil.as @@ -19,8 +19,7 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -package com.threerings.flash { - +package com.threerings.flash { /** * Collection of math utility functions. @@ -34,6 +33,55 @@ public class MathUtil { return Math.min(Math.max(n, min), max); } + + /** + * Returns distance from point (x1, y1) to (x2, y2) in 2D. + * + *

Supports various distance metrics: the common Euclidean distance, taxicab distance, + * arbitrary Minkowski distances, and Chebyshev distance. + * + *

See the NIST web page on + * distance definitions.

+ * + * @param x1 x value of the first point + * @param y1 y value of the first point + * @param x2 x value of the second point + * @param y2 y value of the second point + * @param p Optional: p value of the norm function. Common cases: + *

+ * Note: p < 1 or p = NaN are treated as equivalent to p = Infinity + */ + public static function distance ( + x1 :Number, y1 :Number, x2 :Number, y2 :Number, p :int = 2) :Number + { + if (! isFinite(p) || p < 1) { + p = Infinity; + } + + var dx :Number = x2 - x1; + var dy :Number = y2 - y1; + + switch (p) { + case 1: + // optimized version for taxicab distance + return dx + dy; + case 2: + // optimized version for Euclidean + return Math.sqrt(dx * dx + dy * dy); + case Infinity: + // optimized version for Chebyshev + return Math.max(dx, dy); + default: + // generic version + var xx :Number = Math.pow(dx, p); + var yy :Number = Math.pow(dy, p); + return Math.pow(xx + yy, 1 / p); + } + } + } }