Skip to content

(breaking) vec3: Rename angle_to -> angle_between #80

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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)