EgtMachKernel 1.6r2 :
- modifiche per gestire fino a 4 assi rotanti contemporaneamente attivi (almeno 2 bloccati) - correzioni e migliorie varie.
This commit is contained in:
+299
-33
@@ -277,6 +277,22 @@ Machine::CalculateKinematicChain( void)
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
// se 3 va bene ( uno dovrà poi avere valore assegnato)
|
||||
if ( m_vCalcRotAx.size() == 3) {
|
||||
// se ultimi due di testa, devo invertirne l'ordine
|
||||
if ( m_vCalcRotAx[1].bHead && m_vCalcRotAx[2].bHead)
|
||||
swap( m_vCalcRotAx[1], m_vCalcRotAx[2]) ;
|
||||
// impongo limiti di corsa sul secondo asse rotante di testa
|
||||
if ( m_vCalcRotAx[2].bHead) {
|
||||
Head* pHead = GetHead( m_nCalcHeadId) ;
|
||||
if ( pHead != nullptr) {
|
||||
m_vCalcRotAx[2].stroke.Min = max( m_vCalcRotAx[2].stroke.Min, pHead->GetRot2Stroke().Min) ;
|
||||
m_vCalcRotAx[2].stroke.Max = min( m_vCalcRotAx[2].stroke.Max, pHead->GetRot2Stroke().Max) ;
|
||||
}
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
// altrimenti non ancora gestito, quindi errore
|
||||
return false ;
|
||||
}
|
||||
@@ -332,18 +348,193 @@ Machine::GetKinematicAxis( int nInd) const
|
||||
return sName ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
Machine::BlockKinematicRotAxis( const string& sName, double dVal)
|
||||
{
|
||||
return BlockKinematicRotAxis( GetAxisId( sName), dVal) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
Machine::BlockKinematicRotAxis( int nId, double dVal)
|
||||
{
|
||||
// verifico identificativo
|
||||
if ( nId == GDB_ID_NULL)
|
||||
return false ;
|
||||
// cerco l'asse rotante di calcolo con questo identificativo
|
||||
for ( size_t i = 0 ; i < m_vCalcRotAx.size() ; ++ i) {
|
||||
if ( m_vCalcRotAx[i].nGrpId == nId) {
|
||||
if ( dVal < m_vCalcRotAx[i].stroke.Min || dVal > m_vCalcRotAx[i].stroke.Max) {
|
||||
m_vCalcRotAx[i].bFixed = false ;
|
||||
return false ;
|
||||
}
|
||||
m_vCalcRotAx[i].bFixed = true ;
|
||||
m_vCalcRotAx[i].dFixVal = dVal ;
|
||||
return true ;
|
||||
}
|
||||
}
|
||||
return false ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
Machine::FreeKinematicRotAxis( const string& sName)
|
||||
{
|
||||
return FreeKinematicRotAxis( GetAxisId( sName)) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
Machine::FreeKinematicRotAxis( int nId)
|
||||
{
|
||||
// verifico identificativo
|
||||
if ( nId == GDB_ID_NULL)
|
||||
return false ;
|
||||
// cerco l'asse rotante di calcolo con questo identificativo
|
||||
for ( size_t i = 0 ; i < m_vCalcRotAx.size() ; ++ i) {
|
||||
if ( m_vCalcRotAx[i].nGrpId == nId) {
|
||||
m_vCalcRotAx[i].bFixed = false ;
|
||||
return true ;
|
||||
}
|
||||
}
|
||||
return false ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
Machine::IsKinematicRotAxisBlocked( int nInd)
|
||||
{
|
||||
int nRotAxTot = int( m_vCalcRotAx.size()) ;
|
||||
if ( nInd < 0 || nInd >= nRotAxTot)
|
||||
return false ;
|
||||
return m_vCalcRotAx[nInd].bFixed ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
Machine::GetAngles( const Vector3d& vtDirT, const Vector3d& vtDirA,
|
||||
int& nStat, double& dAngA1, double& dAngB1, double& dAngA2, double& dAngB2) const
|
||||
{
|
||||
// assegno dati
|
||||
Vector3d vtDirH = m_vtCalcDir ;
|
||||
Vector3d vtDirI = m_vtCalcADir ;
|
||||
int nNumRotAx = 0 ;
|
||||
KinAxis RotAx1 ;
|
||||
if ( m_vCalcRotAx.size() >= 1) {
|
||||
++ nNumRotAx ;
|
||||
RotAx1 = m_vCalcRotAx[0] ;
|
||||
}
|
||||
KinAxis RotAx2 ;
|
||||
if ( m_vCalcRotAx.size() >= 2) {
|
||||
++ nNumRotAx ;
|
||||
RotAx2 = m_vCalcRotAx[1] ;
|
||||
}
|
||||
|
||||
// eseguo calcolo
|
||||
return GetMyAngles( vtDirT, vtDirA, vtDirH, vtDirI, nNumRotAx, RotAx1, RotAx2,
|
||||
nStat, dAngA1, dAngB1, dAngA2, dAngB2) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
Machine::GetAngles( const Vector3d& vtDirT, const Vector3d& vtDirA,
|
||||
int& nStat, DBLVECTOR& vAng1, DBLVECTOR& vAng2) const
|
||||
{
|
||||
// verifiche e aggiustamenti degli assi rotanti
|
||||
Vector3d vtDirTm = vtDirT ;
|
||||
Vector3d vtDirAm = vtDirA ;
|
||||
Vector3d vtDirH = m_vtCalcDir ;
|
||||
Vector3d vtDirI = m_vtCalcADir ;
|
||||
int nNumRotAx = 0 ;
|
||||
KinAxis RotAx[2] ;
|
||||
INTVECTOR vBloHeAx ;
|
||||
for ( size_t i = 0 ; i < m_vCalcRotAx.size() ; ++ i) {
|
||||
// se asse libero
|
||||
if ( ! m_vCalcRotAx[i].bFixed) {
|
||||
// verifico di non superare il limite
|
||||
if ( nNumRotAx >= 2)
|
||||
return false ;
|
||||
// assegno l'asse
|
||||
RotAx[nNumRotAx] = m_vCalcRotAx[i] ;
|
||||
// se asse di testa, lo aggiorno con precedenti bloccati di testa (applicati in ordine contrario)
|
||||
if ( RotAx[nNumRotAx].bHead) {
|
||||
for ( size_t k = vBloHeAx.size() ; k >= 1 ; -- k) {
|
||||
int nA = vBloHeAx[k-1] ;
|
||||
RotAx[nNumRotAx].ptPos.Rotate( m_vCalcRotAx[nA].ptPos, m_vCalcRotAx[nA].vtDir, m_vCalcRotAx[nA].dFixVal) ;
|
||||
RotAx[nNumRotAx].vtDir.Rotate( m_vCalcRotAx[nA].vtDir, m_vCalcRotAx[nA].dFixVal) ;
|
||||
}
|
||||
}
|
||||
// incremento contatore
|
||||
++ nNumRotAx ;
|
||||
}
|
||||
// altrimenti asse bloccato
|
||||
else {
|
||||
// se asse di tavola
|
||||
if ( ! m_vCalcRotAx[i].bHead) {
|
||||
// aggiorno direzioni utensile e ausiliaria richieste
|
||||
vtDirTm.Rotate( m_vCalcRotAx[i].vtDir, m_vCalcRotAx[i].dFixVal) ;
|
||||
vtDirAm.Rotate( m_vCalcRotAx[i].vtDir, m_vCalcRotAx[i].dFixVal) ;
|
||||
// aggiorno eventuali assi già inseriti (sicuramente di tavola)
|
||||
for ( size_t j = 0 ; int( j) < nNumRotAx ; ++ j) {
|
||||
RotAx[j].ptPos.Rotate( m_vCalcRotAx[i].ptPos, m_vCalcRotAx[i].vtDir, m_vCalcRotAx[i].dFixVal) ;
|
||||
RotAx[j].vtDir.Rotate( m_vCalcRotAx[i].vtDir, m_vCalcRotAx[i].dFixVal) ;
|
||||
}
|
||||
}
|
||||
// altrimenti asse di testa
|
||||
else {
|
||||
// inserisco in lista assi di testa bloccati
|
||||
vBloHeAx.push_back( int( i)) ;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
// aggiorno direzioni utensile e ausiliaria su testa con eventuali assi bloccati di testa (applico in ordine contrario)
|
||||
for ( size_t k = vBloHeAx.size() ; k >= 1 ; -- k) {
|
||||
int nA = vBloHeAx[k-1] ;
|
||||
vtDirH.Rotate( m_vCalcRotAx[nA].vtDir, m_vCalcRotAx[nA].dFixVal) ;
|
||||
vtDirI.Rotate( m_vCalcRotAx[nA].vtDir, m_vCalcRotAx[nA].dFixVal) ;
|
||||
}
|
||||
|
||||
// eseguo calcolo
|
||||
double dAngA1, dAngB1, dAngA2, dAngB2 ;
|
||||
if ( ! GetMyAngles( vtDirTm, vtDirAm, vtDirH, vtDirI, nNumRotAx, RotAx[0], RotAx[1],
|
||||
nStat, dAngA1, dAngB1, dAngA2, dAngB2))
|
||||
return false ;
|
||||
// assegno gli angoli
|
||||
int nRotAxInd = 1 ;
|
||||
for ( size_t i = 0 ; i < m_vCalcRotAx.size() ; ++i) {
|
||||
if ( m_vCalcRotAx[i].bFixed) {
|
||||
vAng1.push_back( m_vCalcRotAx[i].dFixVal) ;
|
||||
vAng2.push_back( m_vCalcRotAx[i].dFixVal) ;
|
||||
}
|
||||
else {
|
||||
if ( nRotAxInd == 1) {
|
||||
vAng1.push_back( dAngA1) ;
|
||||
vAng2.push_back( dAngA2) ;
|
||||
}
|
||||
else if ( nRotAxInd == 2) {
|
||||
vAng1.push_back( dAngB1) ;
|
||||
vAng2.push_back( dAngB2) ;
|
||||
}
|
||||
else
|
||||
return false ;
|
||||
++ nRotAxInd ;
|
||||
}
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
Machine::GetMyAngles( const Vector3d& vtDirT, const Vector3d& vtDirA,
|
||||
const Vector3d& vtDirH, const Vector3d& vtDirI,
|
||||
int nNumRotAx, const KinAxis& RotAx1, const KinAxis& RotAx2,
|
||||
int& nStat, double& dAngA1, double& dAngB1, double& dAngA2, double& dAngB2) const
|
||||
{
|
||||
// annullo tutti gli angoli
|
||||
nStat = 0 ; dAngA1 = 0 ; dAngB1 = 0 ; dAngA2 = 0 ; dAngB2 = 0 ;
|
||||
// se nessun asse rotante, non c'è alcunchè da calcolare
|
||||
if ( m_vCalcRotAx.size() == 0) {
|
||||
nStat = 1 ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
// direzione fresa normalizzata
|
||||
Vector3d vtDirTn = vtDirT ;
|
||||
if ( ! vtDirTn.Normalize())
|
||||
@@ -352,50 +543,61 @@ Machine::GetAngles( const Vector3d& vtDirT, const Vector3d& vtDirA,
|
||||
Vector3d vtDirAn = vtDirA ;
|
||||
vtDirAn.Normalize() ;
|
||||
// direzione fresa su testa a riposo
|
||||
Vector3d vtDirH = m_vtCalcDir ;
|
||||
Vector3d vtDirHn = vtDirH ;
|
||||
// direzione ausiliaria su testa a riposo
|
||||
Vector3d vtDirI = m_vtCalcADir ;
|
||||
Vector3d vtDirIn = vtDirI ;
|
||||
|
||||
// se nessun asse rotante, devo solo verificare corrispondenza tra direzione richiesta e fresa
|
||||
if ( nNumRotAx == 0) {
|
||||
if ( AreSameVectorApprox( vtDirTn, vtDirHn))
|
||||
nStat = 1 ;
|
||||
else
|
||||
nStat = 0 ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
// direzione primo asse rotante
|
||||
Vector3d vtAx1 = m_vCalcRotAx[0].vtDir ;
|
||||
// se asse di tavola, ne inverto la direzione
|
||||
if ( ! m_vCalcRotAx[0].bHead)
|
||||
if ( ! RotAx1.bHead)
|
||||
vtAx1.Invert() ;
|
||||
// componente versore fresa desiderato su direzione primo asse rotante
|
||||
double dCompTSuAxR1 = vtDirTn * vtAx1 ;
|
||||
|
||||
// se c'è secondo asse rotante, si calcola angolo per avere il componente appena calcolato
|
||||
bool bDet = true ;
|
||||
Vector3d vtDirH1, vtDirH2 ;
|
||||
Vector3d vtDirI1, vtDirI2 ;
|
||||
if ( m_vCalcRotAx.size() == 2) {
|
||||
if ( nNumRotAx == 2) {
|
||||
// direzione secondo asse rotante
|
||||
Vector3d vtAx2 = m_vCalcRotAx[1].vtDir ;
|
||||
Vector3d vtAx2 = RotAx2.vtDir ;
|
||||
// se asse di tavola, ne inverto la direzione
|
||||
if ( ! m_vCalcRotAx[1].bHead)
|
||||
if ( ! RotAx2.bHead)
|
||||
vtAx2.Invert() ;
|
||||
// calcolo secondo angolo di rotazione
|
||||
nStat = GetRotationComponent( vtDirH, dCompTSuAxR1, vtAx1, vtAx2, dAngB1, dAngB2, bDet) ;
|
||||
nStat = GetRotationComponent( vtDirHn, dCompTSuAxR1, vtAx1, vtAx2, dAngB1, dAngB2, bDet) ;
|
||||
// aggiornamento direzioni fresa e ausiliaria su testa
|
||||
if ( nStat >= 1) {
|
||||
// se indeterminato lo azzero
|
||||
if ( ! bDet)
|
||||
dAngB1 = 0 ;
|
||||
// eseguo aggiornamento
|
||||
vtDirH1 = vtDirH ;
|
||||
vtDirH1 = vtDirHn ;
|
||||
vtDirH1.Rotate( vtAx2, dAngB1) ;
|
||||
vtDirI1 = vtDirI ;
|
||||
vtDirI1 = vtDirIn ;
|
||||
vtDirI1.Rotate( vtAx2, dAngB1) ;
|
||||
}
|
||||
if ( nStat == 2) {
|
||||
vtDirH2 = vtDirH ;
|
||||
vtDirH2 = vtDirHn ;
|
||||
vtDirH2.Rotate( vtAx2, dAngB2) ;
|
||||
vtDirI2 = vtDirI ;
|
||||
vtDirI2 = vtDirIn ;
|
||||
vtDirI2.Rotate( vtAx2, dAngB2) ;
|
||||
}
|
||||
}
|
||||
// altrimenti verifico se compatibili
|
||||
else {
|
||||
// componente versore utensile su direzione primo asse
|
||||
double dCompHSuAxR1 = vtDirH * vtAx1 ;
|
||||
double dCompHSuAxR1 = vtDirHn * vtAx1 ;
|
||||
// componenti versori fresa e utensile perpendicolari direzione primo asse
|
||||
double dTemp = 1 - dCompTSuAxR1 * dCompTSuAxR1 ;
|
||||
double dCompTOrtAxR1 = ( ( dTemp > EPS_ZERO) ? sqrt( dTemp) : 0) ;
|
||||
@@ -405,8 +607,8 @@ Machine::GetAngles( const Vector3d& vtDirT, const Vector3d& vtDirA,
|
||||
const double SIN_ANG_ERROR = sin( 0.002 * DEGTORAD) ;
|
||||
if ( fabs( dCompTOrtAxR1 * dCompHSuAxR1 - dCompHOrtAxR1 * dCompTSuAxR1) < SIN_ANG_ERROR) {
|
||||
nStat = 1 ;
|
||||
vtDirH1 = vtDirH ;
|
||||
vtDirI1 = vtDirI ;
|
||||
vtDirH1 = vtDirHn ;
|
||||
vtDirI1 = vtDirIn ;
|
||||
// reset secondo angolo
|
||||
dAngB1 = 0 ;
|
||||
}
|
||||
@@ -469,12 +671,14 @@ Machine::GetAngles( const Vector3d& vtDirT, const Vector3d& vtDirA,
|
||||
// verifiche dei limiti di corsa
|
||||
if ( nStat >= 2) {
|
||||
// se non riesco ad aggiustare, elimino
|
||||
if ( ! AdjustAngleInStroke( 1, dAngA2) || ! AdjustAngleInStroke( 2, dAngB2))
|
||||
if ( ! AdjustAngleInStroke( RotAx1.stroke, dAngA2) ||
|
||||
( nNumRotAx == 2 && ! AdjustAngleInStroke( RotAx2.stroke, dAngB2)))
|
||||
-- nStat ;
|
||||
}
|
||||
if ( nStat >= 1) {
|
||||
// se non riesco ad aggiustare, elimino
|
||||
if ( ! AdjustAngleInStroke( 1, dAngA1) || ! AdjustAngleInStroke( 2, dAngB1)) {
|
||||
if ( ! AdjustAngleInStroke( RotAx1.stroke, dAngA1) ||
|
||||
( nNumRotAx == 2 && ! AdjustAngleInStroke( RotAx2.stroke, dAngB1))) {
|
||||
-- nStat ;
|
||||
// riloco eventuale soluzione rimasta
|
||||
if ( nStat >= 1) {
|
||||
@@ -497,7 +701,28 @@ Machine::GetPositions( const Point3d& ptP, double dAngA, double dAngB,
|
||||
int& nStat, double& dX, double& dY, double& dZ) const
|
||||
{
|
||||
// la posizione deve essere espressa rispetto allo ZERO MACCHINA
|
||||
// per ora gestisco solo gli assi rotanti di testa
|
||||
|
||||
// posizione punto di lavoro con pezzo immobile
|
||||
Point3d ptW = ptP ;
|
||||
|
||||
// se c'è primo asse rotante di tavola
|
||||
if ( m_vCalcRotAx.size() >= 1 && ! m_vCalcRotAx[0].bHead) {
|
||||
// posizione e direzione primo asse rotante
|
||||
Point3d ptAx1 = m_vCalcRotAx[0].ptPos ;
|
||||
Vector3d vtAx1 = m_vCalcRotAx[0].vtDir ;
|
||||
// ruoto punto di lavoro
|
||||
ptW.Rotate( ptAx1, vtAx1, dAngA) ;
|
||||
}
|
||||
|
||||
// se c'è secondo asse rotante di tavola
|
||||
if ( m_vCalcRotAx.size() >= 2 && ! m_vCalcRotAx[1].bHead) {
|
||||
// posizione e direzione primo asse rotante
|
||||
Point3d ptAx2 = m_vCalcRotAx[1].ptPos ;
|
||||
Vector3d vtAx2 = m_vCalcRotAx[1].vtDir ;
|
||||
// ruoto punto di lavoro
|
||||
ptW.Rotate( ptAx2, vtAx2, dAngB) ;
|
||||
}
|
||||
|
||||
|
||||
// posizione e direzione fresa su testa a riposo
|
||||
Point3d ptPosH = m_ptCalcPos ;
|
||||
@@ -533,9 +758,54 @@ Machine::GetPositions( const Point3d& ptP, double dAngA, double dAngB,
|
||||
Vector3d vtDtTL = vtDirH * m_dCalcTLen ;
|
||||
|
||||
// calcolo le posizioni degli assi lineari
|
||||
dX = ptP.x + vtDtHe.x + vtDtAx.x + vtDtTL.x ;
|
||||
dY = ptP.y + vtDtHe.y + vtDtAx.y + vtDtTL.y ;
|
||||
dZ = ptP.z + vtDtHe.z + vtDtAx.z + vtDtTL.z ;
|
||||
dX = ptW.x + vtDtHe.x + vtDtAx.x + vtDtTL.x ;
|
||||
dY = ptW.y + vtDtHe.y + vtDtAx.y + vtDtTL.y ;
|
||||
dZ = ptW.z + vtDtHe.z + vtDtAx.z + vtDtTL.z ;
|
||||
|
||||
// tutto ok
|
||||
nStat = 0 ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
Machine::GetPositions( const Point3d& ptP, DBLVECTOR vAng,
|
||||
int& nStat, double& dX, double& dY, double& dZ) const
|
||||
{
|
||||
// la posizione deve essere espressa rispetto allo ZERO MACCHINA
|
||||
|
||||
// aggiorno punto di lavoro mediante ciclo diretto sugli assi di tavola
|
||||
Point3d ptW = ptP ;
|
||||
for ( size_t i = 0 ; i < m_vCalcRotAx.size() ; ++ i) {
|
||||
// se asse di tavola
|
||||
if ( ! m_vCalcRotAx[i].bHead)
|
||||
ptW.Rotate( m_vCalcRotAx[i].ptPos, m_vCalcRotAx[i].vtDir, vAng[i]) ;
|
||||
}
|
||||
|
||||
// aggiorno posizione e direzione fresa su testa a riposo mediante ciclo inverso sugli assi di testa
|
||||
Point3d ptPosH = m_ptCalcPos ;
|
||||
Vector3d vtDirH = m_vtCalcDir ;
|
||||
for ( size_t i = m_vCalcRotAx.size() ; i >= 1 ; -- i) {
|
||||
// se asse di testa
|
||||
if ( m_vCalcRotAx[i-1].bHead) {
|
||||
ptPosH.Rotate( m_vCalcRotAx[i-1].ptPos, m_vCalcRotAx[i-1].vtDir, vAng[i-1]) ;
|
||||
vtDirH.Rotate( m_vCalcRotAx[i-1].vtDir, vAng[i-1]) ;
|
||||
}
|
||||
}
|
||||
|
||||
// assegno l'offset testa
|
||||
Vector3d vtDtHe = ORIG - m_ptCalcPos ;
|
||||
|
||||
// calcolo il recupero degli assi : è l'opposto dello spostamento della posizione
|
||||
Vector3d vtDtAx = m_ptCalcPos - ptPosH ;
|
||||
|
||||
// calcolo il recupero di lunghezza utensile
|
||||
Vector3d vtDtTL = vtDirH * m_dCalcTLen ;
|
||||
|
||||
// calcolo le posizioni degli assi lineari
|
||||
dX = ptW.x + vtDtHe.x + vtDtAx.x + vtDtTL.x ;
|
||||
dY = ptW.y + vtDtHe.y + vtDtAx.y + vtDtTL.y ;
|
||||
dZ = ptW.z + vtDtHe.z + vtDtAx.z + vtDtTL.z ;
|
||||
|
||||
// tutto ok
|
||||
nStat = 0 ;
|
||||
@@ -639,18 +909,14 @@ Machine::VerifyScc( const Vector3d& vtDirI, const Vector3d& vtDirA, int nSolCh)
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
Machine::AdjustAngleInStroke( int nId, double& dAng) const
|
||||
Machine::AdjustAngleInStroke( const STROKE& Stroke, double& dAng) const
|
||||
{
|
||||
// se angolo fittizio (non esiste l'asse rotante corrispondente), non c'è alcunchè da fare
|
||||
if ( nId <= 0 || nId > int( m_vCalcRotAx.size()))
|
||||
return true ;
|
||||
// eseguo gli aggiustamenti
|
||||
while ( dAng < m_vCalcRotAx[nId-1].stroke.Min)
|
||||
while ( dAng < Stroke.Min)
|
||||
dAng += ANG_FULL ;
|
||||
while ( dAng > m_vCalcRotAx[nId-1].stroke.Max)
|
||||
while ( dAng > Stroke.Max)
|
||||
dAng -= ANG_FULL ;
|
||||
return ( dAng >= m_vCalcRotAx[nId-1].stroke.Min &&
|
||||
dAng <= m_vCalcRotAx[nId-1].stroke.Max) ;
|
||||
return ( dAng >= Stroke.Min && dAng <= Stroke.Max) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user