Files
EgtNumKernel/ShortestPathZigZag.cpp
SaraP ec9e4b4c76 EgtNumKernel 2.3k1 :
- in ShortestPath aumentato il numero max di punti consentiti.
2021-11-18 09:34:24 +01:00

182 lines
6.2 KiB
C++

//----------------------------------------------------------------------------
// EgalTech 2015-2015
//----------------------------------------------------------------------------
// File : ShortestPathZigZag.cpp Data : 22.12.15 Versione : 1.6l4
// Contenuto : Calcolo del percorso minimo per strisce parallele.
// Le coordinate di inizio e fine di ogni punto sono considerate
// coincidenti.
//
//
// Modifiche : 22.12.15 DS Creazione modulo.
//
//
//----------------------------------------------------------------------------
//--------------------------- Include ----------------------------------------
#include "stdafx.h"
#include "DllMain.h"
#include "ShortestPath.h"
#include "/EgtDev/Include/EGnStringUtils.h"
using namespace std ;
//----------------------------------------------------------------------------
#if defined( _DEBUG)
#define MY_LOG(szOut) LOG_INFO( GetENkLogger(), szOut) ;
#else
#define MY_LOG(szOut) ;
#endif
//----------------------------------------------------------------------------
enum { SORT_NONE = 0,
SORT_X_INC = 1,
SORT_X_DEC = 2,
SORT_Y_INC = 3,
SORT_Y_DEC = 4} ;
const double LIN_TOL = 0.1 ;
//----------------------------------------------------------------------------
int
GetMainSort( int nType)
{
switch ( nType) {
case IShortestPath::SP_ZIGZAG_X :
case IShortestPath::SP_ONEWAY_XP :
case IShortestPath::SP_ONEWAY_XM :
return SORT_Y_INC ;
case IShortestPath::SP_ZIGZAG_Y :
case IShortestPath::SP_ONEWAY_YP :
case IShortestPath::SP_ONEWAY_YM :
return SORT_X_INC ;
default :
return SORT_NONE ;
}
}
//----------------------------------------------------------------------------
int
GetStepSort( int nType, int nPrevSort)
{
switch ( nType) {
case IShortestPath::SP_ZIGZAG_X :
return ( nPrevSort == SORT_X_INC) ? SORT_X_DEC : SORT_X_INC ;
case IShortestPath::SP_ZIGZAG_Y :
return ( nPrevSort == SORT_Y_INC) ? SORT_Y_DEC : SORT_Y_INC ;
case IShortestPath::SP_ONEWAY_XP :
return SORT_X_INC ;
case IShortestPath::SP_ONEWAY_XM :
return SORT_X_DEC ;
case IShortestPath::SP_ONEWAY_YP :
return SORT_Y_INC ;
case IShortestPath::SP_ONEWAY_YM :
return SORT_Y_DEC ;
default :
return SORT_NONE ;
}
}
//----------------------------------------------------------------------------
void
SortPaths( SpPoint aPoints[], unsigned aIndices[], unsigned nNumPnts, int nSort)
{
// Bubble sort
for ( unsigned i = 0 ; i < nNumPnts ; ++ i) {
for ( unsigned j = nNumPnts - 1 ; j > i ; -- j) {
bool bSwap = false ;
switch ( nSort) {
default:
case SORT_X_INC :
if ( abs( aPoints[aIndices[j]].dXi - aPoints[aIndices[j - 1]].dXi) < LIN_TOL)
bSwap = ( aPoints[aIndices[j]].dYi < aPoints[aIndices[j - 1]].dYi) ;
else
bSwap = ( aPoints[aIndices[j]].dXi < aPoints[aIndices[j - 1]].dXi) ;
break ;
case SORT_X_DEC :
if ( abs( aPoints[aIndices[j]].dXi - aPoints[aIndices[j - 1]].dXi) < LIN_TOL)
bSwap = ( aPoints[aIndices[j]].dYi < aPoints[aIndices[j - 1]].dYi) ;
else
bSwap = ( aPoints[aIndices[j]].dXi > aPoints[aIndices[j - 1]].dXi + LIN_TOL) ;
break ;
case SORT_Y_INC :
if ( abs( aPoints[aIndices[j]].dYi - aPoints[aIndices[j - 1]].dYi) < LIN_TOL)
bSwap = ( aPoints[aIndices[j]].dXi < aPoints[aIndices[j - 1]].dXi) ;
else
bSwap = ( aPoints[aIndices[j]].dYi < aPoints[aIndices[j - 1]].dYi) ;
break ;
case SORT_Y_DEC :
if ( abs( aPoints[aIndices[j]].dYi - aPoints[aIndices[j - 1]].dYi) < LIN_TOL)
bSwap = ( aPoints[aIndices[j]].dXi < aPoints[aIndices[j - 1]].dXi) ;
else
bSwap = ( aPoints[aIndices[j]].dYi > aPoints[aIndices[j - 1]].dYi) ;
break ;
}
if ( bSwap)
swap( aIndices[j], aIndices[j - 1]) ;
}
}
}
//----------------------------------------------------------------------------
bool
ShortestPath::ZigZag( void)
{
// Almeno un punto
if ( m_nNumPnts < 1)
return false ;
// Ordino i percorsi secondo la direzione di avanzamento principale
int nSort = GetMainSort( m_nType) ;
for ( unsigned i = 0 ; i < m_nNumPnts ; ++ i)
m_nOrder[i] = i ;
SortPaths( m_Points, m_nOrder, m_nNumPnts, nSort) ;
bool bGroupOnX = ( nSort == SORT_X_INC) ;
// Fino a quando non ho ordinato tutti percorsi
unsigned nCount = 0 ;
unsigned i = 0 ;
nSort = GetStepSort( m_nType, SORT_NONE) ;
while ( nCount < m_nNumPnts) {
// Cerco i percorsi che appartengono al range
if ( bGroupOnX) {
double dRange = m_Points[m_nOrder[nCount]].dXi + m_dStep ;
for ( i = nCount + 1 ; i < m_nNumPnts && m_Points[m_nOrder[i]].dXi < dRange - LIN_TOL ; ++ i)
;
}
else {
double dRange = m_Points[m_nOrder[nCount]].dYi + m_dStep ;
for ( i = nCount + 1 ; i < m_nNumPnts && m_Points[m_nOrder[i]].dYi < dRange - LIN_TOL ; ++ i)
;
}
// Ordino i percorsi trovati
SortPaths( m_Points, &m_nOrder[nCount], i - nCount, nSort) ;
nCount = i ;
nSort = GetStepSort( m_nType, nSort) ;
}
// ne calcolo il risultato
m_nMinCost = TotalCost() ;
string sOut = "-- ZigZag/OneWay : TotalCost = " + to_string( m_nMinCost) ;
MY_LOG( sOut.c_str()) ;
return true ;
}
//----------------------------------------------------------------------------
long long unsigned
ShortestPath::TotalCost( void)
{
long long unsigned nCost = 0 ;
// ciclo sui nodi
for ( unsigned i = 1 ; i < m_nNumPnts ; ++ i) {
double dDx = m_Points[m_nOrder[i]].dXi - m_Points[m_nOrder[i-1]].dXi ;
double dDy = m_Points[m_nOrder[i]].dYi - m_Points[m_nOrder[i-1]].dYi ;
double dDz = m_Points[m_nOrder[i]].dZi - m_Points[m_nOrder[i-1]].dZi ;
nCost += (long long unsigned)( sqrt( dDx * dDx + dDy * dDy + dDz * dDz)) ;
}
return nCost ;
}