diff --git a/modules/vec3.lua b/modules/vec3.lua index ed8ea05..b466028 100644 --- a/modules/vec3.lua +++ b/modules/vec3.lua @@ -318,6 +318,11 @@ 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) +end + --- Return a boolean showing if a table is or is not a vec3. -- @tparam vec3 a Vector to be tested -- @treturn boolean is_vec3 diff --git a/spec/vec3_spec.lua b/spec/vec3_spec.lua index 8621fee..d620eca 100644 --- a/spec/vec3_spec.lua +++ b/spec/vec3_spec.lua @@ -224,4 +224,30 @@ describe("vec3:", function() temp = temp:flip_z() 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)) + 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') + + 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') + + 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') + end) end)