Vector math improvements zefram/use
authorZefram <zefram@fysh.org>
Thu, 24 Jul 2014 12:49:15 +0000 (13:49 +0100)
committerZefram <zefram@fysh.org>
Fri, 8 Aug 2014 23:38:25 +0000 (00:38 +0100)
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.

builtin/common/misc_helpers.lua
builtin/common/vector.lua
doc/lua_api.txt

index f57efc138dc2cd1a92535254a70fedaa00c943d6..76fdee8d8d8466a0a8f9898d145aff1a4e4be147 100644 (file)
@@ -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
 
 --------------------------------------------------------------------------------
index 88ccfe6da4fead4c298ba22acd392c8e46796a1c..dfb4fb0e8d65fbada69ed7a752be3b5f62bb2ddb 100644 (file)
@@ -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)
index 19269ebf54cc7289f2dc4994f84ff03db3210a0c..7955f9dc4ffebef59175f418d202483a9b238698 100644 (file)
@@ -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