280 lines
6.8 KiB
Lua
280 lines
6.8 KiB
Lua
-- EgtPoint3d.lua by EgalTech s.r.l. 2019/03/31
|
|
|
|
-- Tavola per definizione modulo (serve ma non usata)
|
|
local EgtPoint3d = {}
|
|
|
|
EgtOutLog( 'EgtPoint3d started', 1)
|
|
|
|
-- Include
|
|
require( 'EgtVector3d')
|
|
--EnableDebug( false)
|
|
|
|
|
|
-- Definizione classe Point3d
|
|
Point3d = {}
|
|
Point3d.__index = Point3d
|
|
|
|
-- funzione di utilita' per identificazione tipo
|
|
function isPoint3d( a)
|
|
return ( getmetatable( a) == Point3d)
|
|
end
|
|
|
|
local function New( x, y, z)
|
|
local p3d = setmetatable( {0,0,0}, Point3d)
|
|
if not x then
|
|
return nil
|
|
elseif isPoint3d( x) then
|
|
p3d[1] = x[1]
|
|
p3d[2] = x[2]
|
|
p3d[3] = x[3]
|
|
elseif type(x) == 'table' and #x >= 3 then
|
|
p3d[1] = x[1]
|
|
p3d[2] = x[2]
|
|
p3d[3] = x[3]
|
|
elseif type( x) == 'number' and type( y) == 'number' and type( z) == 'number' then
|
|
p3d[1] = x
|
|
p3d[2] = y
|
|
p3d[3] = z
|
|
else
|
|
error( 'A parameter is wrong', 2)
|
|
end
|
|
return p3d
|
|
end
|
|
|
|
setmetatable( Point3d, { __call = function( _, ...) return New(...) end })
|
|
|
|
-- opposto di un punto (unary -)
|
|
function Point3d:__unm()
|
|
return New( - self[1], - self[2], - self[3])
|
|
end
|
|
|
|
-- somma di due punti o un punto e un vettore (+)
|
|
function Point3d.__add( a, b)
|
|
if ( isPoint3d( a) and ( isPoint3d( b) or isVector3d( b))) or
|
|
( isPoint3d( b) and ( isPoint3d( a) or isVector3d( a))) then
|
|
return New( a[1] + b[1], a[2] + b[2], a[3] + b[3])
|
|
else
|
|
error( 'A parameter is wrong', 2)
|
|
end
|
|
end
|
|
|
|
-- sottrazione di due punti o un punto e un vettore, restituisce un vettore o un punto (-)
|
|
function Point3d.__sub( a, b)
|
|
if isPoint3d( a) and isPoint3d( b) then
|
|
return Vector3d( a[1] - b[1], a[2] - b[2], a[3] - b[3])
|
|
elseif ( isPoint3d( a) and isVector3d( b)) or ( isVector3d( a) and isPoint3d( b)) then
|
|
return New( a[1] - b[1], a[2] - b[2], a[3] - b[3])
|
|
else
|
|
error( 'A parameter is wrong', 2)
|
|
end
|
|
end
|
|
|
|
-- moltiplicazione di un punto per un numero, di un numero per un punto (*)
|
|
function Point3d.__mul( a, b)
|
|
if type( a) == 'number' and isPoint3d( b) then
|
|
return New( a * b[1], a * b[2], a * b[3])
|
|
elseif isPoint3d( a) and type( b) == 'number' then
|
|
return New( a[1] * b, a[2] * b, a[3] * b)
|
|
else
|
|
error( 'A parameter is wrong', 2)
|
|
end
|
|
end
|
|
|
|
-- divisione di un punto per un numero (/)
|
|
function Point3d.__div( a, b)
|
|
if isPoint3d( a) and type( b) == 'number' then
|
|
return New( a[1] / b, a[2] / b, a[3] / b)
|
|
else
|
|
error( 'A parameter is wrong', 2)
|
|
end
|
|
end
|
|
|
|
-- traslazione
|
|
function Point3d:move( m)
|
|
if not isPoint3d( self) then
|
|
return false
|
|
end
|
|
if isVector3d( m) or ( type( m) == 'table' and #m >= 3) then
|
|
self[1] = self[1] + m[1]
|
|
self[2] = self[2] + m[2]
|
|
self[3] = self[3] + m[3]
|
|
return true
|
|
else
|
|
return false
|
|
end
|
|
end
|
|
|
|
-- rotazione
|
|
function Point3d:rotate( ptAx, vtAx, dAngDeg)
|
|
if not isPoint3d( self) or not isPoint3d( ptAx) or not isVector3d( vtAx) or not type( dAngDeg) == 'number' then
|
|
return false
|
|
end
|
|
local bOk, pRot = EgtPointRotate( self, ptAx, vtAx, dAngDeg)
|
|
if bOk then
|
|
self[1] = pRot[1]
|
|
self[2] = pRot[2]
|
|
self[3] = pRot[3]
|
|
end
|
|
return bOk
|
|
end
|
|
|
|
-- mirror
|
|
function Point3d:mirror( ptOn, vtN)
|
|
if not isPoint3d( self) or not isPoint3d( ptOn) or not isVector3d( vtN) then
|
|
return false
|
|
end
|
|
local bOk, pMir = EgtPointMirror( self, ptOn, vtN)
|
|
if bOk then
|
|
self[1] = pMir[1]
|
|
self[2] = pMir[2]
|
|
self[3] = pMir[3]
|
|
end
|
|
return bOk
|
|
end
|
|
|
|
-- trasformazione di riferimento verso globale
|
|
function Point3d:toGlob( fTool)
|
|
if not isPoint3d( self) or not isFrame3d( fTool) then
|
|
return false
|
|
end
|
|
local bOk, pNew = EgtPointToGlob( self, fTool)
|
|
if bOk then
|
|
self[1] = pNew[1]
|
|
self[2] = pNew[2]
|
|
self[3] = pNew[3]
|
|
end
|
|
return bOk
|
|
end
|
|
|
|
-- trasformazione di riferimento verso locale
|
|
function Point3d:toLoc( fTool)
|
|
if not isPoint3d( self) or not isFrame3d( fTool) then
|
|
return false
|
|
end
|
|
local bOk, pNew = EgtPointToLoc( self, fTool)
|
|
if bOk then
|
|
self[1] = pNew[1]
|
|
self[2] = pNew[2]
|
|
self[3] = pNew[3]
|
|
end
|
|
return bOk
|
|
end
|
|
|
|
-- trasformazione di riferimento da locale a locale
|
|
function Point3d:locToLoc( fOri, fDest)
|
|
if not isPoint3d( self) or not isFrame3d( fOri) or not isFrame3d( fDest) then
|
|
return false
|
|
end
|
|
local bOk, pNew = EgtPointLocToLoc( self, fOri, fDest)
|
|
if bOk then
|
|
self[1] = pNew[1]
|
|
self[2] = pNew[2]
|
|
self[3] = pNew[3]
|
|
end
|
|
return bOk
|
|
end
|
|
|
|
-- restituzione componenti
|
|
function Point3d:getX()
|
|
return self[1]
|
|
end
|
|
|
|
function Point3d:getY()
|
|
return self[2]
|
|
end
|
|
|
|
function Point3d:getZ()
|
|
return self[3]
|
|
end
|
|
|
|
-- conversione in stringa (tostring)
|
|
function Point3d:__tostring()
|
|
return "(" .. EgtNumToString( self[1], 4) .. ", "
|
|
.. EgtNumToString( self[2], 4) .. ", "
|
|
.. EgtNumToString( self[3], 4) .. ")"
|
|
end
|
|
|
|
|
|
-- calcolo quadrato della distanza tra due punti
|
|
function sqdist( a, b)
|
|
if isPoint3d( a) and isPoint3d( b) then
|
|
return ( ( a[1] - b[1]) * ( a[1] - b[1]) +
|
|
( a[2] - b[2]) * ( a[2] - b[2]) +
|
|
( a[3] - b[3]) * ( a[3] - b[3]))
|
|
else
|
|
error( 'A parameter is not a Point3d', 2)
|
|
end
|
|
end
|
|
|
|
-- calcolo distanza tra due punti
|
|
function dist( a, b)
|
|
if isPoint3d( a) and isPoint3d( b) then
|
|
return math.sqrt( ( a[1] - b[1]) * ( a[1] - b[1]) +
|
|
( a[2] - b[2]) * ( a[2] - b[2]) +
|
|
( a[3] - b[3]) * ( a[3] - b[3]))
|
|
else
|
|
error( 'A parameter is not a Point3d', 2)
|
|
end
|
|
end
|
|
|
|
-- funzioni di confronto
|
|
function AreSamePointApprox( a, b)
|
|
if isPoint3d( a) and isPoint3d( b) then
|
|
return ( a - b):isSmall()
|
|
else
|
|
return false
|
|
end
|
|
end
|
|
|
|
function AreSamePointExact( a, b)
|
|
if isPoint3d( a) and isPoint3d( b) then
|
|
return ( a - b):isZero()
|
|
else
|
|
return false
|
|
end
|
|
end
|
|
|
|
function AreSamePointEpsilon( a, b, eps)
|
|
if isPoint3d( a) and isPoint3d( b) then
|
|
return sqdist( a, b) < eps * eps
|
|
else
|
|
return false
|
|
end
|
|
end
|
|
|
|
-- Creazione di punti da stringhe di tre numeri
|
|
function PointFromString( sVal)
|
|
if not sVal then
|
|
return nil
|
|
end
|
|
local vsVal = EgtSplitString( sVal)
|
|
if not vsVal then
|
|
return nil
|
|
end
|
|
if #vsVal < 3 then
|
|
return nil
|
|
end
|
|
return Point3d( tonumber( vsVal[1]), tonumber( vsVal[2]), tonumber( vsVal[3]))
|
|
end
|
|
|
|
-- Creazione di punti da info di entità GeomDB
|
|
function PointFromInfo( nId, sKey)
|
|
PointFromString( EgtGetInfo( nId, sKey))
|
|
end
|
|
|
|
-- Punti notevoli
|
|
function ORIG()
|
|
return Point3d(0,0,0)
|
|
end
|
|
|
|
-- Punto con num aggiunto
|
|
function Point4d( P1, P2, P3, P4)
|
|
if isPoint3d( P1) and ( not P2 or type( P2) == 'number') then
|
|
return { P1[1], P1[2], P1[3], P2 or 0}
|
|
elseif type( P1) == 'number' and type( P2) == 'number' and type( P3) == 'number' and ( not P4 or type( P4) == 'number') then
|
|
return { P1, P2, P3, P4 or 0}
|
|
end
|
|
end
|
|
|
|
return EgtPoint3d
|