summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorubq323 <ubq323@ubq323.website>2025-11-02 20:14:06 +0000
committerubq323 <ubq323@ubq323.website>2025-11-02 20:14:06 +0000
commit8a7513e67adf4076d7c256976c4a86fa936ff1a6 (patch)
treeee64fad4bdabdba326681a219f35e92e106f2e26
parent3027464a66505cefe10ade1d83466c582a2c3ae8 (diff)
pos: add __unm round rot sproj proj angle, inline arithmetic, and make norm of 0 be 0HEADtrunk
-rw-r--r--pos.lua24
1 files changed, 23 insertions, 1 deletions
diff --git a/pos.lua b/pos.lua
index 18d559b..ba1a404 100644
--- a/pos.lua
+++ b/pos.lua
@@ -1,4 +1,5 @@
local class = require'r.class'
+local rmath = require'r.math'
local Pos = class()
function Pos.new(cls)
@@ -18,6 +19,7 @@ end
function Pos.__sub(self,other)
return Pos:make(self.x-other.x,self.y-other.y)
end
+function Pos.__unm(self) return Pos(-self.x,-self.y) end
function Pos.__mul(a,b)
if type(a) == "number" then
return Pos:make(a*b.x,a*b.y)
@@ -35,13 +37,16 @@ end
function Pos.__eq(a,b) return a.x==b.x and a.y==b.y end
function Pos.lensq(self) return self.x^2 + self.y^2 end
function Pos.len(self) return math.sqrt(self:lensq()) end
-function Pos.norm(self) return self/self:len() end
+function Pos.norm(self)
+ local l = self:len()
+ if l < 0.00001 then return Pos(0,0) else return self/l end end
function Pos.l1(self) return math.abs(self.x) + math.abs(self.y) end
function Pos.linf(self) return math.max(math.abs(self.x),math.abs(self.y)) end
function Pos.dot(self,other) return self.x*other.x+self.y*other.y end
function Pos.vals(self) return self.x, self.y end
function Pos.floor(self) return Pos:make(math.floor(self.x),math.floor(self.y)) end
function Pos.ceil(self) return Pos:make(math.ceil(self.x),math.ceil(self.y)) end
+function Pos.round(self) return Pos:make(rmath.round(self.x),rmath.round(self.y)) end
function Pos.divmod(self,size) local div = (self/size):floor() return div, self-div*size end
function Pos.__tostring(self)
return string.format("(%.2f,%.2f)",self.x,self.y)
@@ -50,7 +55,24 @@ function Pos.key(self) return self.x .. ':' .. self.y end
function Pos.unkey(cls,k)
local a,b = k:match"(%-?%d+):(%-?%d+)"
return Pos(tonumber(a),tonumber(b)) end
+function Pos.rot(self,a)
+ local c,s = math.cos(a),math.sin(a)
+ -- [ C, -S ]
+ -- [ S, C ]
+ return Pos(self.x*c - self.y*s, self.x*s + self.y*c) end
+function Pos.sproj(self,b) return self:dot(b:norm()) end
+function Pos.proj(self,b) return self:sproj(b)*b:norm() end
+function Pos.angle(self) return (math.atan2 or math.atan)(self.y,self.x) end
+
+-- inplace arithmetic
+function Pos.addby (self,by) self.x=self.x+by.x self.y=self.y+by.y end
+function Pos.addbyv(self,x,y)self.x=self.x+x self.y=self.y+y end
+function Pos.subby (self,by) self.x=self.x-by.x self.y=self.y-by.y end
+function Pos.subbyv(self,x,y)self.x=self.x-x self.y=self.y-y end
+function Pos.mulby (self,by) self.x=self.x*by self.y=self.y*by end
+function Pos.divby (self,by) self.x=self.x/by self.y=self.y/by end
return Pos
+