From 0a9896f9d0b66c2c5925d54d5a8db35d5ad41dba Mon Sep 17 00:00:00 2001 From: Erich Schubert Date: Wed, 26 Jun 2024 22:26:48 +0200 Subject: [PATCH 1/3] Add vector.random_direction() Generate a random vector of unit length. Useful for many mods. --- builtin/common/vector.lua | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/builtin/common/vector.lua b/builtin/common/vector.lua index e2008a9d7..04bc409d4 100644 --- a/builtin/common/vector.lua +++ b/builtin/common/vector.lua @@ -375,6 +375,24 @@ function vector.in_area(pos, min, max) (pos.z >= min.z) and (pos.z <= max.z) end +function vector.random_direction() + -- Generate a random direction of unit length, via rejection sampling + local x = math.random(-1,1) + local y = math.random(-1,1) + local z = math.random(-1,1) + local l2 = x*x + y*y + z*z -- squared length + -- expected less than two attempts on average + while (l2 > 1 or l2 == 0) do -- rejected, retry + x = math.random(-1,1) + y = math.random(-1,1) + z = math.random(-1,1) + l2 = x*x + y*y + z*z + end + -- normalize + local l = math.sqrt(l2) + return fast_new(x/l, y/l, z/l) +end + if rawget(_G, "core") and core.set_read_vector and core.set_push_vector then local function read_vector(v) return v.x, v.y, v.z From affde8fa0b16e6e9178859cb1a575b98c95c0648 Mon Sep 17 00:00:00 2001 From: Erich Schubert Date: Thu, 27 Jun 2024 10:31:38 +0200 Subject: [PATCH 2/3] Updated random_direction --- builtin/common/vector.lua | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/builtin/common/vector.lua b/builtin/common/vector.lua index 04bc409d4..be82401c3 100644 --- a/builtin/common/vector.lua +++ b/builtin/common/vector.lua @@ -377,17 +377,11 @@ end function vector.random_direction() -- Generate a random direction of unit length, via rejection sampling - local x = math.random(-1,1) - local y = math.random(-1,1) - local z = math.random(-1,1) - local l2 = x*x + y*y + z*z -- squared length - -- expected less than two attempts on average - while (l2 > 1 or l2 == 0) do -- rejected, retry - x = math.random(-1,1) - y = math.random(-1,1) - z = math.random(-1,1) + local x, y, z, l2 + repeat -- expected less than two attempts on average (volume sphere vs. cube) + x, y, z = math.random() * 2 - 1, math.random() * 2 - 1, math.random() * 2 - 1 l2 = x*x + y*y + z*z - end + until l2 <= 1 and l2 >= 1e-6 -- normalize local l = math.sqrt(l2) return fast_new(x/l, y/l, z/l) From 3a76251bc39faea8c138d68686a0ef552181e28d Mon Sep 17 00:00:00 2001 From: Erich Schubert Date: Thu, 27 Jun 2024 14:28:45 +0200 Subject: [PATCH 3/3] add documentation to lua_api.md --- doc/lua_api.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/lua_api.md b/doc/lua_api.md index ee1f4060b..0b19bb53d 100644 --- a/doc/lua_api.md +++ b/doc/lua_api.md @@ -3825,6 +3825,8 @@ vectors are written like this: `(x, y, z)`: `vector.new(v)` does the same as `vector.copy(v)` * `vector.zero()`: * Returns a new vector `(0, 0, 0)`. +* `vector.random_direction()`: + * Returns a new vector of length 1, pointing into a direction chosen uniformly at random. * `vector.copy(v)`: * Returns a copy of the vector `v`. * `vector.from_string(s[, init])`: