Files
refactorwall/ProgramData/EgtCAM5/LuaLibs/EgtBBox3d.lua
Carlo Baronchelli 741791a0e4 Copia locale Iniziale
2022-05-19 16:04:07 +02:00

314 lines
7.9 KiB
Lua

-- EgtBBox3d.lua by EgalTech s.r.l. 2021/12/26
-- Tavola per definizione modulo (serve ma non usata)
local EgtBBox3d = {}
EgtOutLog( 'EgtBBox3d started', 1)
-- Include
require( 'EgtPoint3d')
--EnableDebug( false)
-- Definizione classe BBox3d
BBox3d = {{},{}}
BBox3d.__index = BBox3d
-- funzione di utilita' per identificazione tipo
function isBBox3d( a)
return ( getmetatable( a) == BBox3d)
end
local function New( a, b)
local b3d = setmetatable( {{GEO.INFINITO,GEO.INFINITO,GEO.INFINITO},{-GEO.INFINITO,-GEO.INFINITO,-GEO.INFINITO}}, BBox3d)
if not a then
b3d[1] = Point3d( GEO.INFINITO, GEO.INFINITO, GEO.INFINITO)
b3d[2] = Point3d( -GEO.INFINITO, -GEO.INFINITO, -GEO.INFINITO)
elseif isBBox3d( a) then
b3d[1] = Point3d( a[1])
b3d[2] = Point3d( a[2])
elseif isBBox3d( a) and isBBox3d( b) then
b3d[1] = Point3d( a[1])
b3d[2] = Point3d( a[2])
BBox3d.AddPoint( b3d, b[1])
BBox3d.AddPoint( b3d, b[2])
elseif type(a) == 'table' and #a >= 2 and
type(a[1]) == 'table' and #a[1] >= 3 and
type(a[2]) == 'table' and #a[2] >= 3 then
b3d[1] = Point3d( GEO.INFINITO, GEO.INFINITO, GEO.INFINITO)
b3d[2] = Point3d( -GEO.INFINITO, -GEO.INFINITO, -GEO.INFINITO)
if a[1][1] < ( a[2][1] + GEO.EPS_SMALL) and
a[1][2] < ( a[2][2] + GEO.EPS_SMALL) and
a[1][3] < ( a[2][3] + GEO.EPS_SMALL) then
BBox3d.AddPoint( b3d, a[1])
BBox3d.AddPoint( b3d, a[2])
end
elseif isPoint3d( a) and isPoint3d( b) then
b3d[1] = Point3d(GEO.INFINITO,GEO.INFINITO,GEO.INFINITO)
b3d[2] = Point3d(-GEO.INFINITO,-GEO.INFINITO,-GEO.INFINITO)
BBox3d.AddPoint( b3d, a)
BBox3d.AddPoint( b3d, b)
elseif isPoint3d( a) then
b3d[1] = Point3d(GEO.INFINITO,GEO.INFINITO,GEO.INFINITO)
b3d[2] = Point3d(-GEO.INFINITO,-GEO.INFINITO,-GEO.INFINITO)
BBox3d.AddPoint( b3d, a)
else
error( 'A parameter is wrong', 2)
end
return b3d
end
setmetatable( BBox3d, { __call = function( _, ...) return New( ...) end })
-- verifico se vuoto
function BBox3d:isEmpty()
-- il minimo non è minore del massimo
return not ( self[1][1] < ( self[2][1] + GEO.EPS_SMALL) and
self[1][2] < ( self[2][2] + GEO.EPS_SMALL) and
self[1][3] < ( self[2][3] + GEO.EPS_SMALL) )
end
-- somma di due box (+)
function BBox3d.__add( a, b)
if isBBox3d( a) and isBBox3d( b) then
return New( a, b)
else
error( 'A parameter is not a BBox3d', 2)
end
end
-- aggiungo box o punto
function BBox3d:Add( a)
if isBBox3d( a) then
if not a:isEmpty() then
self:AddPoint( a[1])
self:AddPoint( a[2])
end
else
self:AddPoint( a)
end
end
-- aggiungo un punto (solo per uso interno)
function BBox3d:AddPoint( ptP)
if ptP[1] < self[1][1] then
self[1][1] = ptP[1]
end
if ptP[2] < self[1][2] then
self[1][2] = ptP[2]
end
if ptP[3] < self[1][3] then
self[1][3] = ptP[3]
end
if ptP[1] > self[2][1] then
self[2][1] = ptP[1]
end
if ptP[2] > self[2][2] then
self[2][2] = ptP[2]
end
if ptP[3] > self[2][3] then
self[2][3] = ptP[3]
end
return true
end
-- espansione isotropa
function BBox3d:expand( dDelta)
if not isBBox3d( self) then
return false
end
if BBox3d.isEmpty(self) then
return true
end
self[1][1] = self[1][1] - dDelta
self[1][2] = self[1][2] - dDelta
self[1][3] = self[1][3] - dDelta
self[2][1] = self[2][1] + dDelta
self[2][2] = self[2][2] + dDelta
self[2][3] = self[2][3] + dDelta
end
-- traslazione
function BBox3d:move( m)
if not isBBox3d( self) then
return false
end
if BBox3d.isEmpty(self) then
return true
end
if isVector3d( m) or ( type( m) == 'table' and #m >= 3) then
self[1][1] = self[1][1] + m[1]
self[1][2] = self[1][2] + m[2]
self[1][3] = self[1][3] + m[3]
self[2][1] = self[2][1] + m[1]
self[2][2] = self[2][2] + m[2]
self[2][3] = self[2][3] + m[3]
return true
else
return false
end
end
function BBox3d:rotate( ptAx, vtAx, dAngDeg)
if not isBBox3d( self) or not isPoint3d( ptAx) or not isVector3d( vtAx) or type( dAngDeg) ~= 'number' then
return false
end
if BBox3d.isEmpty(self) then
return true
end
local bOk, b3New = EgtBBoxRotate( self, ptAx, vtAx, dAngDeg)
if bOk then
self[1] = Point3d( b3New[1])
self[2] = Point3d( b3New[2])
end
return bOk
end
-- trasformazione di riferimento verso globale
function BBox3d:toGlob( fTool)
if not isBBox3d( self) or not isFrame3d( fTool) then
return false
end
if BBox3d.isEmpty(self) then
return true
end
local bOk, b3New = EgtBBoxToGlob( self, fTool)
if bOk then
self[1] = Point3d( b3New[1])
self[2] = Point3d( b3New[2])
end
return bOk
end
-- trasformazione di riferimento verso locale
function BBox3d:toLoc( fTool)
if not isBBox3d( self) or not isFrame3d( fTool) then
return false
end
if BBox3d.isEmpty(self) then
return true
end
local bOk, b3New = EgtBBoxToLoc( self, fTool)
if bOk then
self[1] = Point3d( b3New[1])
self[2] = Point3d( b3New[2])
end
return bOk
end
-- trasformazione di riferimento da locale a locale
function BBox3d:locToLoc( fOri, fDest)
if not isBBox3d( self) or not isFrame3d( fOri) or not isFrame3d( fDest) then
return false
end
if BBox3d.isEmpty(self) then
return true
end
local bOk, b3New = EgtBBoxLocToLoc( self, fOri, fDest)
if bOk then
self[1] = Point3d( b3New[1])
self[2] = Point3d( b3New[2])
end
return bOk
end
-- restituzione componenti
function BBox3d:getMin()
if BBox3d.isEmpty(self) then
return nil
end
return Point3d( self[1])
end
function BBox3d:getMax()
if BBox3d.isEmpty(self) then
return nil
end
return Point3d( self[2])
end
function BBox3d:getDimX()
if BBox3d.isEmpty(self) then
return nil
end
return ( self[2][1] - self[1][1])
end
function BBox3d:getDimY()
if BBox3d.isEmpty(self) then
return nil
end
return ( self[2][2] - self[1][2])
end
function BBox3d:getDimZ()
if BBox3d.isEmpty(self) then
return nil
end
return ( self[2][3] - self[1][3])
end
function BBox3d:getCenter()
if BBox3d.isEmpty(self) then
return nil
end
return 0.5 * ( Point3d( self[1]) + Point3d( self[2]))
end
function BBox3d:getRadius()
if BBox3d.isEmpty(self) then
return nil
end
return 0.5 * dist( Point3d( self[1]), Point3d( self[2]))
end
-- conversione in stringa (tostring)
function BBox3d:__tostring()
if BBox3d.isEmpty(self) then
return '(empty)'
end
return '('.. tostring(self[1])..','..tostring(self[2])..')'
end
-- verifica che il box includa il punto in XY
function EnclosesPointXY( b3Box, ptP)
if b3Box[2][1] < ptP[1] - GEO.EPS_SMALL or b3Box[1][1] > ptP[1] + GEO.EPS_SMALL then
return false
end
if b3Box[2][2] < ptP[2] - GEO.EPS_SMALL or b3Box[1][2] > ptP[2] + GEO.EPS_SMALL then
return false
end
return true
end
-- verifica che il primo box includa il secondo in XY
function EnclosesXY( b3First, b3Second)
if not isBBox3d( b3First) or not isBBox3d( b3Second) then
return false
end
if BBox3d.isEmpty( b3First) or BBox3d.isEmpty( b3Second) then
return false
end
return EnclosesPointXY( b3First, b3Second:getMin()) and EnclosesPointXY( b3First, b3Second:getMax())
end
-- verifica di interferenza tra due box in XY
function OverlapsXY( b3First, b3Second)
if not isBBox3d( b3First) or not isBBox3d( b3Second) then
return false
end
if BBox3d.isEmpty( b3First) or BBox3d.isEmpty( b3Second) then
return false
end
if b3First[2][1] < b3Second[1][1] - GEO.EPS_SMALL or b3First[1][1] > b3Second[2][1] + GEO.EPS_SMALL then
return false
end
if b3First[2][2] < b3Second[1][2] - GEO.EPS_SMALL or b3First[1][2] > b3Second[2][2] + GEO.EPS_SMALL then
return false
end
return true
end
return EgtBBox3d