Adding utility classes/objects like Vector and Point
camchenry opened this issue · 15 comments
I came here by way of the post about Hacktober on love2d forums. I have never used this library before, but it looks quite interesting. You said you were thinking about adding vectors, so I am making this issue to start some discussion on if/how they should be implemented.
Great! Thanks for the interest!
If objects are used, I think they would have to be accepted as arguments by all functions.
There might be some conflict of when when you're passing objects vs when you're passing variables to the function, which may cause some trouble.
My idea is that there would be a simple Lua class that creates all these objects. Something like:
local function isObject( obj )
return obj.__type and obj.__isMlibObject
end
local function typeOfObject( obc, expected )
return obj.__type == expected
end
local classes = {
point = function( x, y ) -- Name of class = func (creation function )
-- You could also add type checking here, etc.
return {
x = x, y = y, __type = 'point', __isMlibObject = true,
checkCircle = function( self, ... )
local input = checkInput( ... )
local x, y, radius
if #input == 1 and isObject( input ) and typeOfObject( input, 'circle' ) then
x, y, radius = point.x, point.y, point.radius
elseif #input == 3 then
x, y, radius = unpack( input )
end,
return circleCheckPoint( self.x, self.y, x, y, radius )
end,
}
end,
-- segment = function ...
}
local function createClass( type, ... )
return classes[type]( ... )
end
This isn't tested, but should be a good baseline.
One potential problem with this implementation is that it would use a lot of memory. Another way you could do this (that would use less memory) would be to use metatables to reference back to the table. In other words, each new object doesn't have every single function
I agree, it seems really clunky to have all of the functions check if the first argument is an object or a number. That code does seem like it would use a lot of memory, but I haven't thoroughly used metatables enough to know if that's a solution. So, I might mess around with that and see if I could get it working.
Metatables don't use any extra memory. Tables are passed by reference, not copied, so using a single table as the meta table for 1000 other tables only gives you the footprint of 1001 tables, not 2000.
Metatables definitely seem like the way to go. What I was doing (above) doesn't really seem suited for this.
Looking at #10, should the point code match the vector code? If that's so, the tables should be tagged with some sort of type property. Otherwise, these functions would be identical:
local function isVector(a)
return type(a.x) == "number" and type(a.y) == "number"
end
local function isPoint(p)
return type(p.x) == "number" and type(p.y) == "number"
end
What exactly do you mean by point? A vector can easily be described as a point already.
Fair enough, that's sort of what I was thinking anyway. Unless there are other specific objects that should be added I think this issue can be closed.
Well, the current vector implementation isn't really an object, so it's actually going more for "duck typing" on that one.
Depending on the scope of this library, there are lots of potential objects that could be added such as matrices of varying sizes, vec3s, etc. mlib has a very different structure to it than my own math library, CPML, which contains many of the same features and isolates modules in a very intuitive and friendly way.
Yeah, due to the way I implemented some functions it was impossible to make it so that files were separated (i.e polygon.lua, etc.) without some weirdness occurring.
Well you don't necessarily need to separate files the same way that we do.
It is helpful, though, since our library references other modules within,
but one large file can do the same thing.
Requiring cpml gives you a table with access to all modules, but you can
require only the modules you need instead
local cpml = require "cpml"
local vector = cpml.vec3(0, 0, 0)
local vec3 = require "cpml.modules.vec3"
local vector = vec3(0, 0, 0)
God dammit GitHub.
local cpml = require "cpml"
local vector = cpml.vec3(0, 0, 0)
local vec3 = require "cpml.modules.vec3"
local vector = vec3(0, 0, 0)
I think it needs to be Lua
, not lua
Nah, it's an issue with email responses.
Oh, okay.