From: Zefram Date: Thu, 24 Jul 2014 12:49:15 +0000 (+0100) Subject: Vector math improvements X-Git-Url: http://81.2.79.47:8989/gitweb/?a=commitdiff_plain;h=refs%2Fheads%2Fzefram%2Fuse;p=zefram%2Fminetest%2Fminetest_engine.git Vector math improvements Rewrite math.hypot() to compute more directly, with far fewer operations. Rewrite vector.length() and vector.distance() to each use a single sqrt operation, rather than two (which they were doing via math.hypot). Add vector.length_square() and vector.distance_square(), which return squared distance more cheaply by omitting the sqrt operation. --- diff --git a/builtin/common/misc_helpers.lua b/builtin/common/misc_helpers.lua index f57efc13..76fdee8d 100644 --- a/builtin/common/misc_helpers.lua +++ b/builtin/common/misc_helpers.lua @@ -127,14 +127,7 @@ assert(string.trim("\n \t\tfoo bar\t ") == "foo bar") -------------------------------------------------------------------------------- function math.hypot(x, y) - local t - x = math.abs(x) - y = math.abs(y) - t = math.min(x, y) - x = math.max(x, y) - if x == 0 then return 0 end - t = t / x - return x * math.sqrt(1 + t * t) + return math.sqrt(x*x + y*y) end -------------------------------------------------------------------------------- diff --git a/builtin/common/vector.lua b/builtin/common/vector.lua index 88ccfe6d..dfb4fb0e 100644 --- a/builtin/common/vector.lua +++ b/builtin/common/vector.lua @@ -18,8 +18,12 @@ function vector.equals(a, b) a.z == b.z end +function vector.length_square(v) + return v.x*v.x + v.y*v.y + v.z*v.z +end + function vector.length(v) - return math.hypot(v.x, math.hypot(v.y, v.z)) + return math.sqrt(vector.length_square(v)) end function vector.normalize(v) @@ -39,11 +43,15 @@ function vector.round(v) } end -function vector.distance(a, b) +function vector.distance_square(a, b) local x = a.x - b.x local y = a.y - b.y local z = a.z - b.z - return math.hypot(x, math.hypot(y, z)) + return x*x + y*y + z*z +end + +function vector.distance(a, b) + return math.sqrt(vector.distance_square(a, b)) end function vector.direction(pos1, pos2) diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 19269ebf..7955f9dc 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -1241,7 +1241,11 @@ vector.new([x[, y, z]]) -> vector ^ x is a table or the x position. vector.direction(p1, p2) -> vector vector.distance(p1, p2) -> number +vector.distance_square(p1, p2) -> number +^ Cheaper than squaring vector.distance(p1, p2) vector.length(v) -> number +vector.length_square(v) -> number +^ Cheaper than squaring vector.length(v) vector.normalize(v) -> vector vector.round(v) -> vector vector.equals(v1, v2) -> bool