EgtGeomKernel (Nst_SurfFr) :
- migliorata e raffinata la classe CAvSurfFrMove.
This commit is contained in:
@@ -140,16 +140,20 @@ MyCAvSimpleSurfFrMove::Translate( const Vector3d& vtDir, double& dLen)
|
||||
if ( scInfoCurr.nType == SCI_LINE_LINE || scInfoCurr.nType == SCI_PNT_LINE) {
|
||||
m_SCollInfo = scInfoCurr ;
|
||||
m_SCollInfo.nChunkM = j ;
|
||||
m_SCollInfo.nLoopM = 0 ;
|
||||
m_SCollInfo.nCrvM = k ;
|
||||
m_SCollInfo.nChunkF = i ;
|
||||
m_SCollInfo.nLoopF = 0 ;
|
||||
m_SCollInfo.nCrvF = l ;
|
||||
}
|
||||
}
|
||||
else if ( dNewLenXY < dPrevLenXY) {
|
||||
m_SCollInfo = scInfoCurr ;
|
||||
m_SCollInfo.nChunkM = j ;
|
||||
m_SCollInfo.nLoopM = 0 ;
|
||||
m_SCollInfo.nCrvM = k ;
|
||||
m_SCollInfo.nChunkF = i ;
|
||||
m_SCollInfo.nLoopF = 0 ;
|
||||
m_SCollInfo.nCrvF = l ;
|
||||
}
|
||||
pCrv2 = ( pCompo2 != nullptr ? pCompo2->GetNextCurve() : nullptr) ;
|
||||
|
||||
@@ -30,7 +30,7 @@ class MyCAvSimpleSurfFrMove
|
||||
const SCollInfo& GetSCollInfo()
|
||||
{ return m_SCollInfo ;}
|
||||
|
||||
private :
|
||||
protected :
|
||||
bool TranslateCurveNoCollisionCurve( const ICurve* pCrv1, const ICurve* pCrv2,
|
||||
const Vector3d& vtDir, double& dLen, SCollInfo& scInfo) ;
|
||||
bool TranslateLineNoCollisionLine( const CurveLine* pLine1, const CurveLine* pLine2,
|
||||
@@ -40,7 +40,7 @@ class MyCAvSimpleSurfFrMove
|
||||
bool RotateLineNoCollisionLine( const CurveLine* pLine1, const CurveLine* pLine2,
|
||||
const Point3d& ptCen, double& dAng) ;
|
||||
|
||||
private :
|
||||
protected :
|
||||
const SurfFlatRegion* m_pRegM ;
|
||||
const SurfFlatRegion* m_pRegF ;
|
||||
SCollInfo m_SCollInfo ;
|
||||
|
||||
+26
-479
@@ -41,7 +41,7 @@ bool
|
||||
CAvSurfFrMove::Translate( const Vector3d& vtDir, double& dLen)
|
||||
{
|
||||
MyCAvSurfFrMove ScdMove( *m_pRegM, *m_pRegF) ;
|
||||
m_CollInfo.nType = CI_NONE ;
|
||||
m_CollInfo.nType = SCI_NONE ;
|
||||
if ( ! ScdMove.Translate( vtDir, dLen))
|
||||
return false ;
|
||||
m_CollInfo = ScdMove.GetCollInfo() ;
|
||||
@@ -53,28 +53,10 @@ bool
|
||||
CAvSurfFrMove::Rotate( const Point3d& ptCen, double& dAng)
|
||||
{
|
||||
MyCAvSurfFrMove ScdMove( *m_pRegM, *m_pRegF) ;
|
||||
m_CollInfo.nType = CI_NONE ;
|
||||
m_CollInfo.nType = SCI_NONE ;
|
||||
return ScdMove.Rotate( ptCen, dAng) ;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// MyCAvSurfFrMove
|
||||
//----------------------------------------------------------------------------
|
||||
MyCAvSurfFrMove::MyCAvSurfFrMove( const ISurfFlatRegion& SfrM, const ISurfFlatRegion& SfrF)
|
||||
{
|
||||
// recupero rappresentazione base della regione mobile
|
||||
m_pRegM = GetBasicSurfFlatRegion( &SfrM) ;
|
||||
// ne verifico lo stato
|
||||
if ( m_pRegM == nullptr || ! m_pRegM->IsValid())
|
||||
m_pRegM = nullptr ;
|
||||
// recupero rappresentazione base della regione fissa
|
||||
m_pRegF = GetBasicSurfFlatRegion( &SfrF) ;
|
||||
// ne verifico lo stato
|
||||
if ( m_pRegF == nullptr || ! m_pRegF->IsValid())
|
||||
m_pRegF = nullptr ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
MyCAvSurfFrMove::Translate( const Vector3d& vtDir, double& dLen)
|
||||
@@ -88,7 +70,7 @@ MyCAvSurfFrMove::Translate( const Vector3d& vtDir, double& dLen)
|
||||
return false ;
|
||||
|
||||
// reset info di collisione
|
||||
m_CollInfo.nType = CI_NONE ;
|
||||
m_SCollInfo.nType = SCI_NONE ;
|
||||
|
||||
// porto il vettore di movimento nel riferimento intrinseco e ne annullo la componente Z
|
||||
Vector3d vtDirL = vtDir ;
|
||||
@@ -142,29 +124,29 @@ MyCAvSurfFrMove::Translate( const Vector3d& vtDir, double& dLen)
|
||||
int l = 0 ;
|
||||
const ICurve* pCrv2 = ( pCompo2 != nullptr ? pCompo2->GetFirstCurve() : pCrv2Loc) ;
|
||||
while ( pCrv2 != nullptr) {
|
||||
CollInfo cInfoCurr ;
|
||||
SCollInfo cInfoCurr ;
|
||||
double dPrevLenXY = dNewLenXY ;
|
||||
if ( ! TranslateCurveNoCollisionCurve( pCrv1, pCrv2, vtDirL, dNewLenXY, cInfoCurr))
|
||||
return false ;
|
||||
if ( abs( dNewLenXY - dPrevLenXY) < EPS_SMALL) {
|
||||
if ( cInfoCurr.nType == CI_LINE_LINE || cInfoCurr.nType == CI_PNT_LINE) {
|
||||
m_CollInfo = cInfoCurr ;
|
||||
m_CollInfo.nChunkM = nCM ;
|
||||
m_CollInfo.nLoopM = nLM ;
|
||||
m_CollInfo.nCrvM = k ;
|
||||
m_CollInfo.nChunkF = nCF ;
|
||||
m_CollInfo.nLoopF = nLF ;
|
||||
m_CollInfo.nCrvF = l ;
|
||||
if ( cInfoCurr.nType == SCI_LINE_LINE || cInfoCurr.nType == SCI_PNT_LINE) {
|
||||
m_SCollInfo = cInfoCurr ;
|
||||
m_SCollInfo.nChunkM = nCM ;
|
||||
m_SCollInfo.nLoopM = nLM ;
|
||||
m_SCollInfo.nCrvM = k ;
|
||||
m_SCollInfo.nChunkF = nCF ;
|
||||
m_SCollInfo.nLoopF = nLF ;
|
||||
m_SCollInfo.nCrvF = l ;
|
||||
}
|
||||
}
|
||||
else if ( dNewLenXY < dPrevLenXY) {
|
||||
m_CollInfo = cInfoCurr ;
|
||||
m_CollInfo.nChunkM = nCM ;
|
||||
m_CollInfo.nLoopM = nLM ;
|
||||
m_CollInfo.nCrvM = k ;
|
||||
m_CollInfo.nChunkF = nCF ;
|
||||
m_CollInfo.nLoopF = nLF ;
|
||||
m_CollInfo.nCrvF = l ;
|
||||
m_SCollInfo = cInfoCurr ;
|
||||
m_SCollInfo.nChunkM = nCM ;
|
||||
m_SCollInfo.nLoopM = nLM ;
|
||||
m_SCollInfo.nCrvM = k ;
|
||||
m_SCollInfo.nChunkF = nCF ;
|
||||
m_SCollInfo.nLoopF = nLF ;
|
||||
m_SCollInfo.nCrvF = l ;
|
||||
}
|
||||
pCrv2 = ( pCompo2 != nullptr ? pCompo2->GetNextCurve() : nullptr) ;
|
||||
++ l ;
|
||||
@@ -182,13 +164,13 @@ MyCAvSurfFrMove::Translate( const Vector3d& vtDir, double& dLen)
|
||||
dLen *= dNewLenXY / dLenXY ;
|
||||
|
||||
// porto i punti e le direzioni di SCollInfo da intrinseco a locale della prima regione
|
||||
if ( m_CollInfo.nType != CI_NONE) {
|
||||
m_CollInfo.ptP1.ToGlob( m_pRegM->m_frF) ;
|
||||
m_CollInfo.vtDirM.ToGlob( m_pRegM->m_frF) ;
|
||||
m_CollInfo.vtDirF.ToGlob( m_pRegM->m_frF) ;
|
||||
if ( m_SCollInfo.nType != SCI_NONE) {
|
||||
m_SCollInfo.ptP1.ToGlob( m_pRegM->m_frF) ;
|
||||
m_SCollInfo.vtDirM.ToGlob( m_pRegM->m_frF) ;
|
||||
m_SCollInfo.vtDirF.ToGlob( m_pRegM->m_frF) ;
|
||||
}
|
||||
if ( m_CollInfo.nType == CI_LINE_LINE)
|
||||
m_CollInfo.ptP2.ToGlob( m_pRegM->m_frF) ;
|
||||
if ( m_SCollInfo.nType == SCI_LINE_LINE)
|
||||
m_SCollInfo.ptP2.ToGlob( m_pRegM->m_frF) ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
@@ -206,7 +188,7 @@ MyCAvSurfFrMove::Rotate( const Point3d& ptCen, double& dAng)
|
||||
return false ;
|
||||
|
||||
// reset info di collisione
|
||||
m_CollInfo.nType = CI_NONE ;
|
||||
m_SCollInfo.nType = SCI_NONE ;
|
||||
|
||||
// porto il centro di rotazione nel riferimento intrinseco e ne annullo la componente Z
|
||||
Point3d ptCenL = ptCen ;
|
||||
@@ -273,438 +255,3 @@ MyCAvSurfFrMove::Rotate( const Point3d& ptCen, double& dAng)
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Massima traslazione da posizione sicura in direzione e con limite dati
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
MyCAvSurfFrMove::TranslateCurveNoCollisionCurve( const ICurve* pCrv1, const ICurve* pCrv2,
|
||||
const Vector3d& vtDir, double& dLen, CollInfo& cInfo)
|
||||
{
|
||||
// se entrambe linee, procedo direttamente
|
||||
if ( pCrv1->GetType() == CRV_LINE && pCrv2->GetType() == CRV_LINE) {
|
||||
const CurveLine* pLine1 = GetBasicCurveLine( pCrv1) ;
|
||||
const CurveLine* pLine2 = GetBasicCurveLine( pCrv2) ;
|
||||
if ( ! TranslateLineNoCollisionLine( pLine1, pLine2, vtDir, dLen, cInfo))
|
||||
return false ;
|
||||
cInfo.vtDirM = pLine1->GetEnd() - pLine1->GetStart() ;
|
||||
cInfo.vtDirF = pLine2->GetEnd() - pLine2->GetStart() ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
// altrimenti confronto le approssimazioni con linee delle curve
|
||||
// determino le due polilinee
|
||||
PolyLine PL1 ;
|
||||
if ( ! pCrv1->ApproxWithLines( LIN_TOL_FINE, ANG_TOL_STD_DEG, ICurve::APL_RIGHT, PL1))
|
||||
return false ;
|
||||
PolyLine PL2 ;
|
||||
if ( ! pCrv2->ApproxWithLines( LIN_TOL_FINE, ANG_TOL_STD_DEG, ICurve::APL_RIGHT, PL2))
|
||||
return false ;
|
||||
// ciclo sulle linee della prima polilinea
|
||||
Point3d ptStart1, ptEnd1 ;
|
||||
bool bPL1 = PL1.GetFirstLine( ptStart1, ptEnd1) ;
|
||||
while ( bPL1) {
|
||||
// definisco la prima linea della coppia
|
||||
CurveLine Line1 ;
|
||||
Line1.Set( ptStart1, ptEnd1) ;
|
||||
// ciclo sulle linee della seconda polilinea
|
||||
Point3d ptStart2, ptEnd2 ;
|
||||
bool bPL2 = PL2.GetFirstLine( ptStart2, ptEnd2) ;
|
||||
while ( bPL2) {
|
||||
// definisco la seconda linea della coppia
|
||||
CurveLine Line2 ;
|
||||
Line2.Set( ptStart2, ptEnd2) ;
|
||||
// confronto le linee
|
||||
CollInfo scInfoCurr ;
|
||||
double dPrevLen = dLen ;
|
||||
if ( ! TranslateLineNoCollisionLine( &Line1, &Line2, vtDir, dLen, scInfoCurr))
|
||||
return false ;
|
||||
if ( dLen < dPrevLen) {
|
||||
cInfo = scInfoCurr ;
|
||||
cInfo.nType = CI_PNT_PNT ;
|
||||
cInfo.vtDirM = ptEnd1 - ptStart1 ;
|
||||
cInfo.vtDirF = ptEnd2 - ptStart2 ;
|
||||
}
|
||||
bPL2 = PL2.GetNextLine( ptStart2, ptEnd2) ;
|
||||
}
|
||||
bPL1 = PL1.GetNextLine( ptStart1, ptEnd1) ;
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Massima traslazione da posizione sicura in direzione e con limite dati
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
MyCAvSurfFrMove::TranslateLineNoCollisionLine( const CurveLine* pLine1, const CurveLine* pLine2,
|
||||
const Vector3d& vtDir, double& dLen, CollInfo& cInfo)
|
||||
{
|
||||
// versore ortogonale al movimento
|
||||
Vector3d vtNorm( vtDir.y, - vtDir.x, 0) ;
|
||||
// coordinate degli estremi dei segmenti nel riferimento formato da O=L1Start X=vtNorm Y=vtDir
|
||||
Point3d ptS1( 0, 0, 0) ;
|
||||
Point3d ptE1( ( pLine1->GetEnd() - pLine1->GetStart()) * vtNorm,
|
||||
( pLine1->GetEnd() - pLine1->GetStart()) * vtDir, 0) ;
|
||||
Point3d ptS2( ( pLine2->GetStart() - pLine1->GetStart()) * vtNorm,
|
||||
( pLine2->GetStart() - pLine1->GetStart()) * vtDir, 0) ;
|
||||
Point3d ptE2( ( pLine2->GetEnd() - pLine1->GetStart()) * vtNorm,
|
||||
( pLine2->GetEnd() - pLine1->GetStart()) * vtDir, 0) ;
|
||||
// perpendicolari esterne alle due linee (nel riferimento sopra definito)
|
||||
Vector3d vtN1( ( ptE1.y - ptS1.y), - ( ptE1.x - ptS1.x), 0) ;
|
||||
Vector3d vtN2( ( ptE2.y - ptS2.y), - ( ptE2.x - ptS2.x), 0) ;
|
||||
// reset info di collisione
|
||||
cInfo.nType = CI_NONE ;
|
||||
// eseguo culling (le linee sono il contorno di una area chiusa)
|
||||
if ( vtN1.y <= 0 || vtN2.y >= 0)
|
||||
return true ;
|
||||
// ordino l'intervallo della prima linea secondo X crescenti
|
||||
if ( ptS1.x > ptE1.x)
|
||||
swap( ptS1, ptE1) ;
|
||||
// ordino l'intervallo della seconda linea secondo X crescenti
|
||||
if ( ptS2.x > ptE2.x)
|
||||
swap( ptS2, ptE2) ;
|
||||
// se gli intervalli non si sovrappongono, non ci sono limiti
|
||||
if ( ptS1.x > ptE2.x - EPS_SMALL || ptS2.x > ptE1.x - EPS_SMALL)
|
||||
return true ;
|
||||
// calcolo il minimo movimento degli estremi interni all'intervallo comune
|
||||
double dNewLen ;
|
||||
// estremo inferiore
|
||||
if ( ptS1.x >= ptS2.x) {
|
||||
double dY2 ;
|
||||
if ( abs( ptE2.x - ptS2.x) < EPS_SMALL)
|
||||
dY2 = min( ptE2.y, ptS2.y) ;
|
||||
else
|
||||
dY2 = ptS2.y + ( ptE2.y - ptS2.y) / ( ptE2.x - ptS2.x) * ( ptS1.x - ptS2.x) ;
|
||||
dNewLen = dY2 - ptS1.y ;
|
||||
if ( abs( ptS1.x - ptS2.x) < EPS_SMALL || abs( ptS1.x - ptE2.x) < EPS_SMALL)
|
||||
cInfo.nType = CI_PNT_PNT ;
|
||||
else
|
||||
cInfo.nType = CI_PNT_LINE ;
|
||||
cInfo.ptP1 = pLine1->GetStart() + ptS1.x * vtNorm + dY2 * vtDir ;
|
||||
}
|
||||
else {
|
||||
double dY1 ;
|
||||
if ( abs( ptE1.x - ptS1.x) < EPS_SMALL)
|
||||
dY1 = max( ptE1.y, ptS1.y) ;
|
||||
else
|
||||
dY1 = ptS1.y + ( ptE1.y - ptS1.y) / ( ptE1.x - ptS1.x) * ( ptS2.x - ptS1.x) ;
|
||||
dNewLen = ptS2.y - dY1 ;
|
||||
if ( abs( ptS2.x - ptS1.x) < EPS_SMALL || abs( ptS2.x - ptE1.x) < EPS_SMALL)
|
||||
cInfo.nType = CI_PNT_PNT ;
|
||||
else
|
||||
cInfo.nType = CI_LINE_PNT ;
|
||||
cInfo.ptP1 = pLine1->GetStart() + ptS2.x * vtNorm + ptS2.y * vtDir ;
|
||||
}
|
||||
// estremo superiore
|
||||
if ( ptE1.x <= ptE2.x) {
|
||||
double dY2 ;
|
||||
if ( abs( ptE2.x - ptS2.x) < EPS_SMALL)
|
||||
dY2 = min( ptE2.y, ptS2.y) ;
|
||||
else
|
||||
dY2 = ptS2.y + ( ptE2.y - ptS2.y) / ( ptE2.x - ptS2.x) * ( ptE1.x - ptS2.x) ;
|
||||
double dCurLen = dY2 - ptE1.y ;
|
||||
if ( abs( dCurLen - dNewLen) < EPS_SMALL) {
|
||||
cInfo.nType = CI_LINE_LINE ;
|
||||
cInfo.ptP2 = pLine1->GetStart() + ptE1.x * vtNorm + dY2 * vtDir ;
|
||||
}
|
||||
else if ( dCurLen < dNewLen) {
|
||||
dNewLen = dCurLen ;
|
||||
if ( abs( ptE1.x - ptS2.x) < EPS_SMALL || abs( ptE1.x - ptE2.x) < EPS_SMALL)
|
||||
cInfo.nType = CI_PNT_PNT ;
|
||||
else
|
||||
cInfo.nType = CI_PNT_LINE ;
|
||||
cInfo.ptP1 = pLine1->GetStart() + ptE1.x * vtNorm + dY2 * vtDir ;
|
||||
}
|
||||
}
|
||||
else {
|
||||
double dY1 ;
|
||||
if ( abs( ptE1.x - ptS1.x) < EPS_SMALL)
|
||||
dY1 = max( ptE1.y, ptS1.y) ;
|
||||
else
|
||||
dY1 = ptS1.y + ( ptE1.y - ptS1.y) / ( ptE1.x - ptS1.x) * ( ptE2.x - ptS1.x) ;
|
||||
double dCurLen = ptE2.y - dY1 ;
|
||||
if ( abs( dCurLen - dNewLen) < EPS_SMALL) {
|
||||
cInfo.nType = CI_LINE_LINE ;
|
||||
cInfo.ptP2 = pLine1->GetStart() + ptE2.x * vtNorm + ptE2.y * vtDir ;
|
||||
}
|
||||
else if ( dCurLen < dNewLen) {
|
||||
dNewLen = dCurLen ;
|
||||
if ( abs( ptE2.x - ptS1.x) < EPS_SMALL || abs( ptE2.x - ptE1.x) < EPS_SMALL)
|
||||
cInfo.nType = CI_PNT_PNT ;
|
||||
else
|
||||
cInfo.nType = CI_LINE_PNT ;
|
||||
cInfo.ptP1 = pLine1->GetStart() + ptE2.x * vtNorm + ptE2.y * vtDir ;
|
||||
}
|
||||
}
|
||||
// confronto con movimento corrente
|
||||
if ( dNewLen > - 5 * EPS_SMALL && dNewLen < EPS_SMALL)
|
||||
dLen = 0 ;
|
||||
else if ( dNewLen > 0 && dNewLen < dLen)
|
||||
dLen = dNewLen ;
|
||||
else // non c'è collisione, reset Info
|
||||
cInfo.nType = CI_NONE ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Massima rotazione da posizione sicura in direzione e con limite dati
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
MyCAvSurfFrMove::RotateCurveNoCollisionCurve( const ICurve* pCrv1, const ICurve* pCrv2, const Point3d& ptCen, double& dAng)
|
||||
{
|
||||
// se entrambe linee, procedo direttamente
|
||||
if ( pCrv1->GetType() == CRV_LINE && pCrv2->GetType() == CRV_LINE) {
|
||||
const CurveLine* pLine1 = GetBasicCurveLine( pCrv1) ;
|
||||
const CurveLine* pLine2 = GetBasicCurveLine( pCrv2) ;
|
||||
if ( ! RotateLineNoCollisionLine( pLine1, pLine2, ptCen, dAng))
|
||||
return false ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
// altrimenti confronto le approssimazioni con linee delle curve
|
||||
// determino le due polilinee
|
||||
PolyLine PL1 ;
|
||||
if ( ! pCrv1->ApproxWithLines( LIN_TOL_FINE, ANG_TOL_STD_DEG, ICurve::APL_RIGHT, PL1))
|
||||
return false ;
|
||||
PolyLine PL2 ;
|
||||
if ( ! pCrv2->ApproxWithLines( LIN_TOL_FINE, ANG_TOL_STD_DEG, ICurve::APL_RIGHT, PL2))
|
||||
return false ;
|
||||
// ciclo sulle linee della prima polilinea
|
||||
Point3d ptStart1, ptEnd1 ;
|
||||
bool bPL1 = PL1.GetFirstLine( ptStart1, ptEnd1) ;
|
||||
while ( bPL1) {
|
||||
// definisco la prima linea della coppia
|
||||
CurveLine Line1 ;
|
||||
Line1.Set( ptStart1, ptEnd1) ;
|
||||
// ciclo sulle linee della seconda polilinea
|
||||
Point3d ptStart2, ptEnd2 ;
|
||||
bool bPL2 = PL2.GetFirstLine( ptStart2, ptEnd2) ;
|
||||
while ( bPL2) {
|
||||
// definisco la seconda linea della coppia
|
||||
CurveLine Line2 ;
|
||||
Line2.Set( ptStart2, ptEnd2) ;
|
||||
// confronto le linee
|
||||
if ( ! RotateLineNoCollisionLine( &Line1, &Line2, ptCen, dAng))
|
||||
return false ;
|
||||
bPL2 = PL2.GetNextLine( ptStart2, ptEnd2) ;
|
||||
}
|
||||
bPL1 = PL1.GetNextLine( ptStart1, ptEnd1) ;
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Massima rotazione da posizione sicura in direzione e con limite dati
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
MyCAvSurfFrMove::RotateLineNoCollisionLine( const CurveLine* pLine1, const CurveLine* pLine2, const Point3d& ptCen, double& dAng)
|
||||
{
|
||||
// senso di rotazione
|
||||
bool bCCW = ( dAng > 0) ;
|
||||
|
||||
// analisi della prima linea
|
||||
Point3d ptS1 = pLine1->GetStart() ;
|
||||
Point3d ptE1 = pLine1->GetEnd() ;
|
||||
Vector3d vtDir1 = ptE1 - ptS1 ;
|
||||
vtDir1.z = 0 ;
|
||||
double dLen1 = vtDir1.LenXY() ;
|
||||
if ( dLen1 < EPS_SMALL)
|
||||
return false ;
|
||||
vtDir1 /= dLen1 ;
|
||||
Vector3d vtN1( vtDir1.y, - vtDir1.x, 0) ;
|
||||
// linea per successivi controlli
|
||||
CurveLine NewLine1 ;
|
||||
// se punto a minima distanza da C non interno al segmento, eseguo direttamente culling su intera linea
|
||||
double dUMin1 = ( ptCen - ptS1) * vtDir1 ;
|
||||
if ( dUMin1 < EPS_SMALL || dUMin1 > dLen1 - EPS_SMALL) {
|
||||
Vector3d vtRad = 0.5 * ( ptE1 + ptS1) - ptCen ;
|
||||
Vector3d vtMove = ( bCCW ? Vector3d( - vtRad.y, vtRad.x, 0) : Vector3d( vtRad.y, - vtRad.x, 0)) ;
|
||||
if ( vtN1 * vtMove <= 0)
|
||||
return true ;
|
||||
}
|
||||
// altrimenti tengo parte con culling superato
|
||||
else {
|
||||
// verifico primo estremo
|
||||
Vector3d vtRad = ptS1 - ptCen ;
|
||||
Vector3d vtMove = ( bCCW ? Vector3d( - vtRad.y, vtRad.x, 0) : Vector3d( vtRad.y, - vtRad.x, 0)) ;
|
||||
// se va bene il primo estremo
|
||||
if ( vtN1 * vtMove > 0) {
|
||||
ptE1 = ptS1 + vtDir1 * dUMin1 ;
|
||||
dLen1 = dUMin1 ;
|
||||
}
|
||||
// altrimenti deve andare bene il secondo
|
||||
else {
|
||||
ptS1 += vtDir1 * dUMin1 ;
|
||||
dLen1 -= dUMin1 ;
|
||||
}
|
||||
NewLine1.Set( ptE1, ptS1) ;
|
||||
pLine1 = &NewLine1 ;
|
||||
}
|
||||
|
||||
// analisi della seconda linea
|
||||
Point3d ptS2 = pLine2->GetStart() ;
|
||||
Point3d ptE2 = pLine2->GetEnd() ;
|
||||
Vector3d vtDir2 = ptE2 - ptS2 ;
|
||||
vtDir2.z = 0 ;
|
||||
double dLen2 = vtDir2.LenXY() ;
|
||||
if ( dLen2 < EPS_SMALL)
|
||||
return false ;
|
||||
vtDir2 /= dLen2 ;
|
||||
Vector3d vtN2( vtDir2.y, - vtDir2.x, 0) ;
|
||||
// linea per successivi controlli
|
||||
CurveLine NewLine2 ;
|
||||
// se punto a minima distanza da C non interno al segmento, eseguo direttamente culling su intera linea
|
||||
double dUMin2 = ( ptCen - ptS2) * vtDir2 ;
|
||||
if ( dUMin2 < EPS_SMALL || dUMin2 > dLen2 - EPS_SMALL) {
|
||||
Vector3d vtRad = 0.5 * ( ptE2 + ptS2) - ptCen ;
|
||||
Vector3d vtMove = ( bCCW ? Vector3d( - vtRad.y, vtRad.x, 0) : Vector3d( vtRad.y, - vtRad.x, 0)) ;
|
||||
if ( vtN2 * vtMove >= 0)
|
||||
return true ;
|
||||
}
|
||||
// altrimenti tengo parte con culling superato
|
||||
else {
|
||||
// verifico primo estremo
|
||||
Vector3d vtRad = ptS2 - ptCen ;
|
||||
Vector3d vtMove = ( bCCW ? Vector3d( - vtRad.y, vtRad.x, 0) : Vector3d( vtRad.y, - vtRad.x, 0)) ;
|
||||
// se va bene il primo estremo
|
||||
if ( vtN2 * vtMove < 0) {
|
||||
ptE2 = ptS2 + vtDir2 * dUMin2 ;
|
||||
dLen2 = dUMin2 ;
|
||||
}
|
||||
// altrimenti deve andare bene il secondo
|
||||
else {
|
||||
ptS2 += vtDir2 * dUMin2 ;
|
||||
dLen2 -= dUMin2 ;
|
||||
}
|
||||
NewLine2.Set( ptE2, ptS2) ;
|
||||
pLine2 = &NewLine2 ;
|
||||
}
|
||||
|
||||
// verifico se gli intervalli radiali si sovrappongono
|
||||
Vector3d vtDirS1 = ptS1 - ptCen ;
|
||||
vtDirS1.z = 0 ;
|
||||
double dRadS1 = vtDirS1.LenXY() ;
|
||||
Vector3d vtDirE1 = ptE1 - ptCen ;
|
||||
vtDirE1.z = 0 ;
|
||||
double dRadE1 = vtDirE1.LenXY() ;
|
||||
Vector3d vtDirS2 = ptS2 - ptCen ;
|
||||
vtDirS2.z = 0 ;
|
||||
double dRadS2 = vtDirS2.LenXY() ;
|
||||
Vector3d vtDirE2 = ptE2 - ptCen ;
|
||||
vtDirE2.z = 0 ;
|
||||
double dRadE2 = vtDirE2.LenXY() ;
|
||||
|
||||
// ordino l'intervallo della prima linea secondo raggi crescenti
|
||||
if ( dRadS1 > dRadE1) {
|
||||
swap( ptS1, ptE1) ;
|
||||
swap( vtDirS1, vtDirE1) ;
|
||||
swap( dRadS1, dRadE1) ;
|
||||
}
|
||||
// ordino l'intervallo della seconda linea secondo raggi crescenti
|
||||
if ( dRadS2 > dRadE2) {
|
||||
swap( ptS2, ptE2) ;
|
||||
swap( vtDirS2, vtDirE2) ;
|
||||
swap( dRadS2, dRadE2) ;
|
||||
}
|
||||
// se gli intervalli non si sovrappongono, non ci sono limiti
|
||||
if ( dRadS1 > dRadE2 - EPS_SMALL || dRadS2 > dRadE1 - EPS_SMALL)
|
||||
return true ;
|
||||
|
||||
// calcolo la minima rotazione degli estremi interni all'intervallo comune
|
||||
double dNewAng = dAng ;
|
||||
if ( ! AreSamePointXYEpsilon( ptS1, ptS2, 10 * EPS_SMALL)) {
|
||||
if ( dRadS1 >= dRadS2) {
|
||||
vtDirS1 /= dRadS1 ;
|
||||
CurveArc ArcS1 ;
|
||||
ArcS1.Set( ptCen, Z_AX, dRadS1, vtDirS1, dAng, 0) ;
|
||||
IntersLineArc intLA( *pLine2, ArcS1) ;
|
||||
if ( intLA.GetNumInters() == 2) {
|
||||
IntCrvCrvInfo iccInfo1, iccInfo2 ;
|
||||
intLA.GetIntCrvCrvInfo( 0, iccInfo1) ;
|
||||
intLA.GetIntCrvCrvInfo( 1, iccInfo2) ;
|
||||
dNewAng = dAng * min( iccInfo1.IciB[0].dU, iccInfo2.IciB[0].dU) ;
|
||||
}
|
||||
else if ( intLA.GetNumInters() == 1) {
|
||||
IntCrvCrvInfo iccInfo ;
|
||||
intLA.GetIntCrvCrvInfo( 0, iccInfo) ;
|
||||
dNewAng = dAng * iccInfo.IciB[0].dU ;
|
||||
}
|
||||
}
|
||||
else {
|
||||
vtDirS2 /= dRadS2 ;
|
||||
CurveArc ArcS2 ;
|
||||
ArcS2.Set( ptCen, Z_AX, dRadS2, vtDirS2, - dAng, 0) ;
|
||||
IntersLineArc intLA( *pLine1, ArcS2) ;
|
||||
if ( intLA.GetNumInters() == 2) {
|
||||
IntCrvCrvInfo iccInfo1, iccInfo2 ;
|
||||
intLA.GetIntCrvCrvInfo( 0, iccInfo1) ;
|
||||
intLA.GetIntCrvCrvInfo( 1, iccInfo2) ;
|
||||
dNewAng = dAng * min( iccInfo1.IciB[0].dU, iccInfo2.IciB[0].dU) ;
|
||||
}
|
||||
else if ( intLA.GetNumInters() == 1) {
|
||||
IntCrvCrvInfo iccInfo ;
|
||||
intLA.GetIntCrvCrvInfo( 0, iccInfo) ;
|
||||
dNewAng = dAng * iccInfo.IciB[0].dU ;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( ! AreSamePointXYEpsilon( ptE1, ptE2, 10 * EPS_SMALL)) {
|
||||
if ( dRadE1 <= dRadE2) {
|
||||
vtDirE1 /= dRadE1 ;
|
||||
CurveArc ArcE1 ;
|
||||
ArcE1.Set( ptCen, Z_AX, dRadE1, vtDirE1, dAng, 0) ;
|
||||
IntersLineArc intLA( *pLine2, ArcE1) ;
|
||||
if ( intLA.GetNumInters() == 2) {
|
||||
IntCrvCrvInfo iccInfo1, iccInfo2 ;
|
||||
intLA.GetIntCrvCrvInfo( 0, iccInfo1) ;
|
||||
intLA.GetIntCrvCrvInfo( 1, iccInfo2) ;
|
||||
if ( bCCW)
|
||||
dNewAng = min( dNewAng, dAng * min( iccInfo1.IciB[0].dU, iccInfo2.IciB[0].dU)) ;
|
||||
else
|
||||
dNewAng = max( dNewAng, dAng * min( iccInfo1.IciB[0].dU, iccInfo2.IciB[0].dU)) ;
|
||||
}
|
||||
else if ( intLA.GetNumInters() == 1) {
|
||||
IntCrvCrvInfo iccInfo ;
|
||||
intLA.GetIntCrvCrvInfo( 0, iccInfo) ;
|
||||
if ( bCCW)
|
||||
dNewAng = min( dNewAng, dAng * iccInfo.IciB[0].dU) ;
|
||||
else
|
||||
dNewAng = max( dNewAng, dAng * iccInfo.IciB[0].dU) ;
|
||||
}
|
||||
}
|
||||
else {
|
||||
vtDirE2 /= dRadE2 ;
|
||||
CurveArc ArcE2 ;
|
||||
ArcE2.Set( ptCen, Z_AX, dRadE2, vtDirE2, - dAng, 0) ;
|
||||
IntersLineArc intLA( *pLine1, ArcE2) ;
|
||||
if ( intLA.GetNumInters() == 2) {
|
||||
IntCrvCrvInfo iccInfo1, iccInfo2 ;
|
||||
intLA.GetIntCrvCrvInfo( 0, iccInfo1) ;
|
||||
intLA.GetIntCrvCrvInfo( 1, iccInfo2) ;
|
||||
if ( bCCW)
|
||||
dNewAng = min( dNewAng, dAng * min( iccInfo1.IciB[0].dU, iccInfo2.IciB[0].dU)) ;
|
||||
else
|
||||
dNewAng = max( dNewAng, dAng * min( iccInfo1.IciB[0].dU, iccInfo2.IciB[0].dU)) ;
|
||||
}
|
||||
else if ( intLA.GetNumInters() == 1) {
|
||||
IntCrvCrvInfo iccInfo ;
|
||||
intLA.GetIntCrvCrvInfo( 0, iccInfo) ;
|
||||
if ( bCCW)
|
||||
dNewAng = min( dNewAng, dAng * iccInfo.IciB[0].dU) ;
|
||||
else
|
||||
dNewAng = max( dNewAng, dAng * iccInfo.IciB[0].dU) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( AreSamePointXYEpsilon( ptS1, ptS2, 10 * EPS_SMALL) &&
|
||||
AreSamePointXYEpsilon( ptE1, ptE2, 10 * EPS_SMALL))
|
||||
dNewAng = 0 ;
|
||||
// confronto con rotazione corrente
|
||||
if ( abs( dNewAng) < EPS_ANG_SMALL)
|
||||
dAng = 0 ;
|
||||
else if ( bCCW && dNewAng > 0)
|
||||
dAng = min( dAng, dNewAng) ;
|
||||
else if ( ! bCCW && dNewAng < 0)
|
||||
dAng = max( dAng, dNewAng) ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
+6
-23
@@ -12,35 +12,18 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "/EgtDev/Include/EGkCAvSurfFrMove.h"
|
||||
|
||||
class CurveLine ;
|
||||
class SurfFlatRegion ;
|
||||
#include "CAvSimpleSurfFrMove.h"
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
class MyCAvSurfFrMove
|
||||
class MyCAvSurfFrMove : public MyCAvSimpleSurfFrMove
|
||||
{
|
||||
public :
|
||||
MyCAvSurfFrMove( const ISurfFlatRegion& SfrM, const ISurfFlatRegion& SfrF) ;
|
||||
MyCAvSurfFrMove( const ISurfFlatRegion& SfrM, const ISurfFlatRegion& SfrF) :
|
||||
MyCAvSimpleSurfFrMove( SfrM, SfrF) {} ;
|
||||
|
||||
public :
|
||||
bool Translate( const Vector3d& vtDir, double& dLen) ;
|
||||
bool Rotate( const Point3d& ptCen, double& dAng) ;
|
||||
const CollInfo& GetCollInfo()
|
||||
{ return m_CollInfo ; }
|
||||
|
||||
private :
|
||||
bool TranslateCurveNoCollisionCurve( const ICurve* pCrv1, const ICurve* pCrv2,
|
||||
const Vector3d& vtDir, double& dLen, CollInfo& cInfo) ;
|
||||
bool TranslateLineNoCollisionLine( const CurveLine* pLine1, const CurveLine* pLine2,
|
||||
const Vector3d& vtDir, double& dLen, CollInfo& cInfo) ;
|
||||
bool RotateCurveNoCollisionCurve( const ICurve* pCrv1, const ICurve* pCrv2,
|
||||
const Point3d& ptCen, double& dAng) ;
|
||||
bool RotateLineNoCollisionLine( const CurveLine* pLine1, const CurveLine* pLine2,
|
||||
const Point3d& ptCen, double& dAng) ;
|
||||
|
||||
private :
|
||||
const SurfFlatRegion* m_pRegM ;
|
||||
const SurfFlatRegion* m_pRegF ;
|
||||
CollInfo m_CollInfo ;
|
||||
const SCollInfo& GetCollInfo()
|
||||
{ return m_SCollInfo ; }
|
||||
} ;
|
||||
|
||||
Reference in New Issue
Block a user