can someone explain to be how to do the following with my vector class?
I am not very sufficient in math because of neglecting school when I was a kid, but I want to have the following functions and operator support in this class..
require("class")
--Construct vec2 class
Vec2 = Class:inherit("Vec2");
function Vec2:create(x,y)
self.x = x or 0;
self.y = y or 0;
end
function Vec2:normalize()
self.x = self.x / self:getLength();
self.y = self.y / self:getLength();
return self;
end
-- did some research and took a guess that this is how this function works
function Vec2:getLength()
return math.sqrt(self.x * self.x + self.y * self.y)
end
function Vec2:setLength(length) end
function Vec2:getDirection() end
function Vec2:setDirection(length) end
--wondering if there might be operator support for doing..
--local vec2a = Vec2(1,0)
--local vec2b = Vec2(4,3)
--local vec2c = vec2a * vec2b
local Vec2 = {}
Vec2.__index = Vec2
setmetatable(Vec2, {
__call = function(_, x, y)
return setmetatable({
x = x or 0,
y = y or 0
}, Vec2)
end
})
--Allows two Vec2 objects to be multiplied together, to produce a new Vec2 object.
function Vec2:__mul(vec2)
return Vec2(self.x * vec2.x, self.y * vec2.y)
end
local vec2a = Vec2(1,0)
local vec2b = Vec2(4,3)
local vec2c = vec2a * vec2b
print(vec2c.x, vec2c.y)
function Vec2:normalize()
self.x = self.x / self:getLength(); -- the vector's length changes at this line
self.y = self.y / self:getLength();
return self;
end
I spent a good little while trying to make .length thing work the way you mentioned it. I don't think I would recommend doing things this way, but here is the code if you're interested in seeing it!
local Vec2 = {}
function Vec2.__index(t, k)
if k == "length" then
return t:getLength()
end
return rawget(Vec2, k) or rawget(t.t, k)
end
function Vec2.__newindex(t, k, v)
if k == "length" then
t:setLength(v)
end
rawset(t.t, k, v)
end
setmetatable(Vec2, {
__call = function(_, x, y)
return setmetatable({
t = {
x = x or 0,
y = y or 0
}
}, Vec2)
end
})
function Vec2:setLength(length)
self:normalize()
rawset(self.t, "length", length)
self.x = self.x * length
self.y = self.y * length
end
function Vec2:getLength()
local length = rawget(self.t, "length")
if length then
return length
end
rawset(self.t, "length", math.sqrt(self.x ^ 2 + self.y ^ 2))
return self.length
end
function Vec2:normalize()
local length = self:getLength()
self.x = self.x / length
self.y = self.y / length
end
local vec2c = Vec2(0, 1)
print(vec2c.x, vec2c.y) --Starting x and y values
print(vec2c.length)
vec2c.length = 4
print(vec2c.x, vec2c.y) --New x and y values
print(vec2c.length)
function Vec2:normalize(unit)
unit = unit or 1
local length = self:getLength()
if length > 0 then -- division by zero check
local n = (1/length)*unit
self.x = self.x*n
self.y = self.y*n
end
return length
end
function Vec2:setLength(length)
self:normalize(length)
end
function Vec2:getLength()
local x, y = self.x, self.y
return math.sqrt(x*x + y*y)
end
The problem with storing "length" is that it may get out of sync when you modify .x or .y.
@ivan: i will fix that thankyou. it was like that originally I just attempted to make it shorter. >.< also thankyou for the the help on the setLength function
@sir_silver: ya that looks complicated I think I will just stick to get and set methods.
how would I go about setting and getting direction?