-- EgtFrame3d.lua by EgalTech s.r.l. 2020/09/29 -- Tavola per definizione modulo (serve ma non usata) local EgtFrame3d = {} EgtOutLog( 'EgtFrame3d started', 1) -- Include require( 'EgtPoint3d') --EnableDebug( false) -- Definizione classe Frame3d Frame3d = {{},{},{},{}} Frame3d.__index = Frame3d -- funzione di utilita' per identificazione tipo function isFrame3d( a) return ( getmetatable( a) == Frame3d) end local function New( a, b, c, d) local f3d = setmetatable( {{0,0,0},{1,0,0},{0,1,0},{0,0,1}}, Frame3d) local function SetVersors( type) if type == GDB_FR.FRONT then f3d[2] = X_AX() ; f3d[3] = Z_AX() ; f3d[4] = -Y_AX() elseif type == GDB_FR.RIGHT then f3d[2] = Y_AX() ; f3d[3] = Z_AX() ; f3d[4] = X_AX() elseif type == GDB_FR.BACK then f3d[2] = -X_AX() ; f3d[3] = Z_AX() ; f3d[4] = Y_AX() elseif type == GDB_FR.LEFT then f3d[2] = -Y_AX() ; f3d[3] = Z_AX() ; f3d[4] = -X_AX() elseif type == GDB_FR.BOTTOM then f3d[2] = X_AX() ; f3d[3] = -Y_AX() ; f3d[4] = -Z_AX() else -- GDB_FR.TOP f3d[2] = X_AX() ; f3d[3] = Y_AX() ; f3d[4] = Z_AX() end end if not a then f3d[1] = Point3d( 0, 0, 0) SetVersors( GDB_FR.TOP) elseif isFrame3d( a) then f3d[1] = a[1] f3d[2] = a[2] f3d[3] = a[3] f3d[4] = a[4] elseif type(a) == 'table' and #a >= 4 and type(a[1]) == 'table' and #a[1] >= 3 and type(a[2]) == 'table' and #a[2] >= 3 and type(a[3]) == 'table' and #a[3] >= 3 and type(a[4]) == 'table' and #a[4] >= 3 then f3d[1] = Point3d( a[1]) f3d[2] = Vector3d( a[2]) f3d[3] = Vector3d( a[3]) f3d[4] = Vector3d( a[4]) f3d[2]:normalize() f3d[3]:normalize() f3d[4]:normalize() if not Frame3d.isValid( f3d) then error( 'Error in FrameIsValid', 2) end elseif isPoint3d( a) and isVector3d( b) and isVector3d( c) and isVector3d( d) then f3d[1] = a f3d[2] = b f3d[3] = c f3d[4] = d f3d[2]:normalize() f3d[3]:normalize() f3d[4]:normalize() if not Frame3d.isValid( f3d) then error( 'Error in FrameIsValid', 2) end elseif isPoint3d( a) and isVector3d( b) then local bOk, Ocs = EgtFrameOCS( a, b) if bOk then f3d[1] = Point3d( Ocs[1]) f3d[2] = Vector3d( Ocs[2]) f3d[3] = Vector3d( Ocs[3]) f3d[4] = Vector3d( Ocs[4]) else error( 'Error in EgtFrameOCS', 2) end elseif isPoint3d( a) and isPoint3d( b) and isPoint3d( c) then local bOk, f3P = EgtFrameFrom3Points( a, b, c) if bOk then f3d[1] = Point3d( f3P[1]) f3d[2] = Vector3d( f3P[2]) f3d[3] = Vector3d( f3P[3]) f3d[4] = Vector3d( f3P[4]) else error( 'Error in EgtFrameFrom3Points', 2) end elseif isPoint3d( a) then f3d[1] = a SetVersors( b) elseif type(a) == 'number' and type( b) == 'number' and type( c) == 'number' then f3d[1] = Point3d( a, b, c) SetVersors( d) else error( 'A parameter is wrong', 2) end return f3d end setmetatable( Frame3d, { __call = function( _, ...) return New( ...) end }) -- verifica validità function Frame3d:isValid() -- verifico che i versori siano normalizzati if not self[2]:isNormalized() or not self[3]:isNormalized() or not self[4]:isNormalized() then return false end -- verifico che i versori siano mutuamente ortogonali if math.abs( self[2][1] * self[3][1] + self[2][2] * self[3][2] + self[2][3] * self[3][3]) > GEO.EPS_ZERO or math.abs( self[3][1] * self[4][1] + self[3][2] * self[4][2] + self[3][3] * self[4][3]) > GEO.EPS_ZERO or math.abs( self[4][1] * self[2][1] + self[4][2] * self[2][2] + self[4][3] * self[2][3]) > GEO.EPS_ZERO then return false end -- verifico il senso destrorso della terna if Vector3d.TripleProd( self[2], self[3], self[4]) < GEO.EPS_ZERO then return false end -- tutto bene return true end -- traslazione function Frame3d:move( m) if not isFrame3d( self) then return false end if isVector3d( m) then self[1] = self[1] + m return true elseif type( m) == 'table' and #m >= 3 then self[1] = self[1] + Vector3d( m) return true else return false end end -- rotazione function Frame3d:rotate( ptAx, vtAx, dAngDeg) if not isFrame3d( self) or not isPoint3d( ptAx) or not isVector3d( vtAx) or type( dAngDeg) ~= 'number' then return false end local bOk, fRot = EgtFrameRotate( self, ptAx, vtAx, dAngDeg) if bOk then self[1] = Point3d( fRot[1]) self[2] = Vector3d( fRot[2]) self[3] = Vector3d( fRot[3]) self[4] = Vector3d( fRot[4]) end return bOk end -- inversione (trasformazione inversa) function Frame3d:invert() if not isFrame3d( self) then return false end local bOk, frInv = EgtFrameToLoc( Frame3d(), self) if bOk then self[1] = Point3d( frInv[1]) self[2] = Vector3d( frInv[2]) self[3] = Vector3d( frInv[3]) self[4] = Vector3d( frInv[4]) end return bOk end -- trasformazione di riferimento verso globale function Frame3d:toGlob( fTool) if not isFrame3d( self) or not isFrame3d( fTool) then return false end local bOk, fNew = EgtFrameToGlob( self, fTool) if bOk then self[1] = Point3d( fNew[1]) self[2] = Vector3d( fNew[2]) self[3] = Vector3d( fNew[3]) self[4] = Vector3d( fNew[4]) end return bOk end -- trasformazione di riferimento verso locale function Frame3d:toLoc( fTool) if not isFrame3d( self) or not isFrame3d( fTool) then return false end local bOk, fNew = EgtFrameToLoc( self, fTool) if bOk then self[1] = Point3d( fNew[1]) self[2] = Vector3d( fNew[2]) self[3] = Vector3d( fNew[3]) self[4] = Vector3d( fNew[4]) end return bOk end -- trasformazione di riferimento da locale a locale function Frame3d:locToLoc( fOri, fDest) if not isFrame3d( self) or not isFrame3d( fOri) or not isFrame3d( fDest) then return false end local bOk, fNew = EgtFrameLocToLoc( self, fOri, fDest) if bOk then self[1] = Point3d( fNew[1]) self[2] = Vector3d( fNew[2]) self[3] = Vector3d( fNew[3]) self[4] = Vector3d( fNew[4]) end return bOk end -- restituzione componenti function Frame3d:getOrigin() return self[1] end function Frame3d:getVersX() return self[2] end function Frame3d:getVersY() return self[3] end function Frame3d:getVersZ() return self[4] end -- conversione in stringa (tostring) function Frame3d:__tostring() return '('.. tostring(self[1])..','..tostring(self[2])..','..tostring(self[3])..','..tostring(self[4]) ..')' end -- Angoli di rotazione di Eulero da Frame function GetRotCAC1FromFrame( frRef) if not isFrame3d( frRef) then return nil end return EgtFrameGetRotCAC1( frRef) end -- Angoli di rotazione attorno ad assi XYZ fissi da Frame function GetFixedAxesRotABCFromFrame( frRef) if not isFrame3d( frRef) then return nil end return EgtFrameGetFixedAxesRotABC( frRef) end -- Riferimenti notevoli function GLOB_FRM() return Frame3d() end return EgtFrame3d