Lua 5.3+ use a two-argument version of math.atan instead of math.atan2.
atan2 exists but is deprecated, so if you use cpml in a lua build that
strips deprecated functions vec2.angle_to will fail.
Output the type that was incorrect to make it more obvious what the user
is doing wrong without them adding logging.
To avoid string building during lots of vector math, introduced a
private precond module that only builds the strings when an error
occurs. It uses error() to put the resulting error message at the caller
to cpml.
Before:
lua: ~/cpml/modules/vec2.lua:52: new: Wrong argument type for x (<number> expected)
lua: ~/cpml/modules/vec2.lua:424: __add: Wrong argument type for right hand operand. (<cpml.vec2> expected)
example stack traceback:
[C]: in function 'assert'
~/cpml/modules/vec2.lua:424: in metamethod '__add'
test_cpml.lua:32: in main chunk
[C]: in ?
After:
lua: test_cpml.lua:31: new: Wrong argument type for x: string (<number> expected)
lua: test_cpml.lua:32: __add: Wrong argument type 'string' for right hand operand. (<cpml.vec2> expected)
example stack traceback:
[C]: in function 'error'
~/cpml/modules/_private_precond.lua:13: in function 'modules._private_precond.assert'
~/cpml/modules/vec2.lua:425: in metamethod '__add'
test_cpml.lua:32: in main chunk
[C]: in ?
The tracebacks are longer, but the initial error is at the location of
the mistake and the output includes the input type.
angle_to was producing the angle from +x to the difference between a,b
which is unexpected. Instead, it should produce the smallest absolute
angle between the two vectors and be signed to indicate the direction of
rotation.
By using the old angle_to implementation and modifying equal() to print
out the failures, you can see the numbers that it was producing before
didn't make much sense:
right:angle_to(down) = 45.0
right:angle_to(left) = 0.0
right:angle_to(up) = -45.0
down:angle_to(right) = -135.0
down:angle_to(left) = -45.0
down:angle_to(up) = -90.0
left:angle_to(down) = 135.0
left:angle_to(up) = -135.0
up:angle_to(right) = 135.0
up:angle_to(down) = 90.0
up:angle_to(left) = 45.0
Now it produces numbers you'd expect:
right:angle_to(down) = -90.0
right:angle_to(left) = 180.0
right:angle_to(up) = 90.0
down:angle_to(right) = 90.0
down:angle_to(left) = -90.0
down:angle_to(up) = 180.0
left:angle_to(down) = 90.0
left:angle_to(up) = -90.0
up:angle_to(right) = -90.0
up:angle_to(down) = 180.0
up:angle_to(left) = 90.0
See also https://stackoverflow.com/questions/21483999/using-atan2-to-find-angle-between-two-vectors
Also added tests for angle_between.
On Github we run unit tests inside "busted". At the start of each test "busted" does some sort of trick (clearing package.loaded)? Which causes "require" to run again for all lua files. This breaks ffi.metatype with error "cannot change a protected metatable" if it is called twice with a single type name, since this is true global state. To work around this this patch wraps ffi.metatype calls in a xpcall() so that failure is silently ignored.
- Added missing vec2 lerp (same as vec3's)
- Added lerp to vec2 and vec3 metatable
- Added tests for vec2 (incomplete)
- Fixed vec2/number being the same as number/vec2
- Fixed vec2 constructor to match vec3's