diff --git a/EgtGeomKernel.rc b/EgtGeomKernel.rc index 1fdd45c..f1391bc 100644 Binary files a/EgtGeomKernel.rc and b/EgtGeomKernel.rc differ diff --git a/PolyLine.cpp b/PolyLine.cpp index 466f77f..846c90d 100644 --- a/PolyLine.cpp +++ b/PolyLine.cpp @@ -1303,21 +1303,34 @@ PolyLine::Trim( const Plane3d& plPlane, bool bInVsOut) //---------------------------------------------------------------------------- bool DistPointPolyLine( const Point3d& ptP, const PolyLine& plPoly, double& dDist) +{ + double dDummy ; + return DistPointPolyLine( ptP, plPoly, dDist, dDummy) ; +} + +//---------------------------------------------------------------------------- +bool +DistPointPolyLine( const Point3d& ptP, const PolyLine& plPoly, double& dDist, double& dMinDistPar) { // La polilinea deve contenere almeno due punti if ( plPoly.GetPointNbr() < 2) return false ; // Ciclo sui punti della polilinea dDist = INFINITO ; + int nSeg = -1 ; Point3d ptStart, ptEnd ; plPoly.GetFirstPoint( ptStart) ; while ( plPoly.GetNextPoint( ptEnd)) { + ++ nSeg ; // distanza del punto dal segmento della polilinea DistPointLine PointLineDistCalc( ptP, ptStart, ptEnd) ; double dPlDist ; PointLineDistCalc.GetDist( dPlDist) ; - if ( dPlDist < dDist) + if ( dPlDist < dDist) { dDist = dPlDist ; + PointLineDistCalc.GetParamAtMinDistPoint( dMinDistPar) ; + dMinDistPar += nSeg ; + } // assegno nuovo inizio ptStart = ptEnd ; } @@ -1409,7 +1422,7 @@ GetPointParamOnPolyLine( const Point3d& ptP, const PolyLine& plPoly, double dTol // Ciclo sui punti della polilinea int nSeg = -1 ; double dMinSqDist = SQ_INFINITO ; - double dMinPar = -1 ; + dPar = -1 ; Point3d ptStart, ptEnd ; plPoly.GetFirstPoint( ptStart) ; while ( plPoly.GetNextPoint( ptEnd)) { @@ -1422,7 +1435,7 @@ GetPointParamOnPolyLine( const Point3d& ptP, const PolyLine& plPoly, double dTol dMinSqDist = dSqDist ; double dSegPar ; dDistCalc.GetParamAtMinDistPoint( dSegPar) ; - dMinPar = nSeg + dSegPar ; + dPar = nSeg + dSegPar ; } // assegno nuovo inizio ptStart = ptEnd ; @@ -1523,7 +1536,7 @@ AssociatePolyLinesMinDistPoints( const PolyLine& PL1, const PolyLine& PL2, PNTIV int nPnt2 = PL2.GetPointNbr() ; if ( nPnt1 == 0 || nPnt2 == 0) return false ; - + bCommonInternalPoints = false ; // indica la presenza di punti interni in comune tra le due polylines vPnt1.reserve( PL1.GetPointNbr()) ; @@ -1545,49 +1558,80 @@ AssociatePolyLinesMinDistPoints( const PolyLine& PL1, const PolyLine& PL2, PNTIV int nTotP2 = int( vPnt2.size()) ; // calcoli per prima curva - int LastJ = 0 ; + int nLastJ = 0 ; vPnt1[0].second = 0 ; + + double dFirstDist, dFirstParMinDist ; + DistPointPolyLine( vPnt1[0].first, PL2, dFirstDist, dFirstParMinDist) ; + int nFirstMinJ = ( int)( dFirstParMinDist + 0.5) ; + for ( int i = 1 ; i < nTotP1 ; ++ i) { - double dSqDistMin = SqDist( vPnt1[i].first, vPnt2[LastJ].first) ; - double dApprDistMin = ApproxDist( vPnt1[i].first, vPnt2[LastJ].first) ; - int MinJ = LastJ ; - for ( int j = LastJ + 1 ; j < nTotP2 ; ++ j) { - double dSqDist = SqDist( vPnt1[i].first, vPnt2[j].first) ; - if ( dSqDist < dSqDistMin - 2 * dApprDistMin * EPS_SMALL) { - dSqDistMin = dSqDist ; - dApprDistMin = ApproxDist( vPnt1[i].first, vPnt2[j].first) ; - MinJ = j ; + + double dDist = INFINITO ; + double dMinDistPar = nLastJ ; + for ( int j = max( nLastJ, 1) ; j < nTotP2 ; ++ j) { + // distanza del punto dal segmento della polilinea + DistPointLine PointLineDistCalc( vPnt1[i].first, vPnt2[j-1].first, vPnt2[j].first) ; + double dPlDist ; + if ( PointLineDistCalc.GetDist( dPlDist) && dPlDist < dDist) { + dDist = dPlDist ; + PointLineDistCalc.GetParamAtMinDistPoint( dMinDistPar) ; + dMinDistPar += j - 1 ; } - else if ( dSqDist > 16 * dSqDistMin) - break ; } - if ( i < nTotP1 - 1 && dSqDistMin < EPS_SMALL) + int nMinJ = ( int)( dMinDistPar + 0.5) ; + + // eventuale correzione per i primi punti ( da forzare nel vertice 0) + if ( nLastJ == 0 && nFirstMinJ > 0.5 * nTotP2 && nMinJ >= nFirstMinJ) + nMinJ = 0 ; + + if ( nMinJ < nLastJ) + nMinJ = nLastJ ; + + // verifica se è un punto interno in comune con l'altra polyline + if ( i < nTotP1 - 1 && dDist < EPS_SMALL && abs( dMinDistPar - floor( dMinDistPar + 0.5)) < EPS_SMALL) bCommonInternalPoints = true ; - vPnt1[i].second = MinJ ; - LastJ = MinJ ; + + vPnt1[i].second = nMinJ ; + nLastJ = nMinJ ; } - + // calcoli per seconda curva - int LastI = 0 ; + int nLastI = 0 ; vPnt2[0].second = 0 ; + + DistPointPolyLine( vPnt2[0].first, PL1, dFirstDist, dFirstParMinDist) ; + int nFirstMinI = ( int)( dFirstParMinDist + 0.5) ; + for ( int j = 1 ; j < nTotP2 ; ++ j) { - double dSqDistMin = SqDist( vPnt2[j].first, vPnt1[LastI].first) ; - double dApprDistMin = ApproxDist( vPnt2[j].first, vPnt1[LastI].first) ; - int MinI = LastI ; - for ( int i = LastI + 1 ; i < nTotP1 ; ++ i) { - double dSqDist = SqDist( vPnt2[j].first, vPnt1[i].first) ; - if ( dSqDist < dSqDistMin - 2 * dApprDistMin * EPS_SMALL) { - dSqDistMin = dSqDist ; - dApprDistMin = ApproxDist( vPnt2[j].first, vPnt1[i].first) ; - MinI = i ; + + double dDist = INFINITO ; + double dMinDistPar = nLastI ; + for ( int i = max( nLastI, 1) ; i < nTotP1 ; ++ i) { + // distanza del punto dal segmento della polilinea + DistPointLine PointLineDistCalc( vPnt2[j].first, vPnt1[i-1].first, vPnt1[i].first) ; + double dPlDist ; + PointLineDistCalc.GetDist( dPlDist) ; + if ( dPlDist < dDist) { + dDist = dPlDist ; + PointLineDistCalc.GetParamAtMinDistPoint( dMinDistPar) ; + dMinDistPar += i - 1 ; } - else if ( dSqDist > 16 * dSqDistMin) - break ; } - if ( j < nTotP2 - 1 && dSqDistMin < EPS_SMALL) + int nMinI = ( int)( dMinDistPar + 0.5) ; + + // eventuale correzione per primi punti + if ( nLastI == 0 && nFirstMinI > 0.5 * nTotP1 && nMinI >= nFirstMinI) + nMinI = 0 ; + + if ( nMinI < nLastI) + nMinI = nLastI ; + + if ( j < nTotP2 - 1 && dDist < EPS_SMALL && abs( dMinDistPar - floor( dMinDistPar + 0.5)) < EPS_SMALL) bCommonInternalPoints = true ; - vPnt2[j].second = MinI ; - LastI = MinI ; + + vPnt2[j].second = nMinI ; + nLastI = nMinI ; } return true ;