Skip to content

Commit

Permalink
vec3: Rename angle_to -> angle_between
Browse files Browse the repository at this point in the history
In vec2, angle_to is signed and angle_between is unsigned. We only have
the unsigned version in vec3, so use the corresponding name.

Remove the vec3 implementation from vec2 and use vec2's style
implementation. It doesn't allocate new vectors and works even if you
somehow call vec3.angle_between(vec2(), vec2()).
  • Loading branch information
idbrii committed Feb 4, 2023
1 parent eb209f6 commit 19e54cf
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 26 deletions.
8 changes: 2 additions & 6 deletions modules/vec2.lua
Original file line number Diff line number Diff line change
Expand Up @@ -257,18 +257,14 @@ end

--- Unsigned angle between two vectors.
-- Directionless and thus commutative.
-- Input vectors must be non-zero.
-- @tparam vec2 a Vector
-- @tparam vec2 b Vector
-- @treturn number angle in [0, pi]
function vec2.angle_between(a, b)
if b then
if vec2.is_vec2(a) then
return acos(a:dot(b) / (a:len() * b:len()))
end

return acos(vec3.dot(a, b) / (vec3.len(a) * vec3.len(b)))
return acos(a:dot(b) / (a:len() * b:len()))
end

return 0
end

Expand Down
18 changes: 15 additions & 3 deletions modules/vec3.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
local modules = (...):gsub('%.[^%.]+$', '') .. "."
local precond = require(modules .. "_private_precond")
local private = require(modules .. "_private_utils")
local acos = math.acos
local sqrt = math.sqrt
local cos = math.cos
local sin = math.sin
Expand Down Expand Up @@ -330,9 +331,20 @@ function vec3.flip_z(a)
return vec3.new(a.x, a.y, -a.z)
end

function vec3.angle_to(a, b)
local v = a:normalize():dot(b:normalize())
return math.acos(v)
-- No angle_to because that requires defining an axis of rotation. Instead you
-- likely want to convert both into vec2 and use vec2.angle_to.

--- Unsigned angle between two vectors.
-- Directionless and thus commutative.
-- Input vectors must be non-zero.
-- @tparam vec3 a Vector
-- @tparam vec3 b Vector
-- @treturn number angle in [0, pi]
function vec3.angle_between(a, b)
if b then
return acos(a:dot(b) / (a:len() * b:len()))
end
return 0
end

--- Return a boolean showing if a table is or is not a vec3.
Expand Down
37 changes: 20 additions & 17 deletions spec/vec3_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -232,30 +232,33 @@ describe("vec3:", function()
assert.is.equal(temp, vec3(-1, -2, -3))
end)

it("get two 3-vectors angle", function()
local angle_to = function(a, b)
local deg = math.deg(a:angle_to(b))
it("gets angle between two 3-vectors", function()
local angle_between = function(a, b)
local deg = math.deg(a:angle_between(b))
return string.format('%.2f', deg)
end

local a = vec3(1,2,3)
assert.is.equal(angle_to(a, vec3(3, 2, 1)), '44.42')
assert.is.equal(angle_to(a, vec3(0, 10, 0)), '57.69')
assert.is.equal(angle_to(a, vec3(0, -12, -10)), '157.51')
assert.is.equal(angle_between(a, a), '0.00')
assert.is.equal(angle_between(a, vec3(3, 2, 1)), '44.42')
assert.is.equal(angle_between(a, vec3(0, 10, 0)), '57.69')
assert.is.equal(angle_between(a, vec3(0, -12, -10)), '157.51')

a = vec3.unit_z
assert.is.equal(angle_to(a, vec3(0, 10, 0)), '90.00')
assert.is.equal(angle_to(a, vec3(-123, 10, 0)), '90.00')
assert.is.equal(angle_to(a, vec3(-10, 0, 10)), '45.00')
assert.is.equal(angle_to(a, vec3(-10, 0, -10)), '135.00')
assert.is.equal(angle_to(a, vec3(0, -10, -10)), '135.00')
assert.is.equal(angle_to(a, vec3(0, 0, -10)), '180.00')
assert.is.equal(angle_to(a, vec3(0, 0, 100)), '0.00')
assert.is.equal(angle_between(a, a), '0.00')
assert.is.equal(angle_between(a, vec3(0, 10, 0)), '90.00')
assert.is.equal(angle_between(a, vec3(-123, 10, 0)), '90.00')
assert.is.equal(angle_between(a, vec3(-10, 0, 10)), '45.00')
assert.is.equal(angle_between(a, vec3(-10, 0, -10)), '135.00')
assert.is.equal(angle_between(a, vec3(0, -10, -10)), '135.00')
assert.is.equal(angle_between(a, vec3(0, 0, -10)), '180.00')
assert.is.equal(angle_between(a, vec3(0, 0, 100)), '0.00')

a = vec3(100, 100, 0)
assert.is.equal(angle_to(a, vec3(0, 0, 100)), '90.00')
assert.is.equal(angle_to(a, vec3(0, 0, -100)), '90.00')
assert.is.equal(angle_to(a, vec3(-10, -10, 0)), '180.00')
assert.is.equal(angle_to(a, vec3.unit_z), '90.00')
assert.is.equal(angle_between(a, a), '0.00')
assert.is.equal(angle_between(a, vec3(0, 0, 100)), '90.00')
assert.is.equal(angle_between(a, vec3(0, 0, -100)), '90.00')
assert.is.equal(angle_between(a, vec3(-10, -10, 0)), '180.00')
assert.is.equal(angle_between(a, vec3.unit_z), '90.00')
end)
end)

0 comments on commit 19e54cf

Please sign in to comment.