//---------------------------------------------------------------------------- // EgalTech 2014-2014 //---------------------------------------------------------------------------- // File : IntersCrvCompoCrvCompo.cpp Data : 24.06.14 Versione : 1.5f6 // Contenuto : Implementazione della classe intersezione curva composita/cc. // // // // Modifiche : 24.06.14 DS Creazione modulo. // // //---------------------------------------------------------------------------- //--------------------------- Include ---------------------------------------- #include "stdafx.h" #include "IntersCrvCompoCrvCompo.h" #include using namespace std ; //---------------------------------------------------------------------------- bool SortGreater( const IntCrvCrvInfo& aInfo1, const IntCrvCrvInfo& aInfo2) { double dU1, dU2 ; // determino il primo termine del confronto dU1 = aInfo1.IciA[0].dU ; if ( aInfo1.bOverlap) { // caso normale if ( aInfo1.IciA[0].dU < aInfo1.IciA[1].dU) dU1 = 0.5 * ( aInfo1.IciA[0].dU + aInfo1.IciA[1].dU) ; // a cavallo di fine / inizio else dU1 = aInfo1.IciA[0].dU + SPAN_PARAM ; } // determino il secondo termine del confronto dU2 = aInfo2.IciA[0].dU ; if ( aInfo2.bOverlap) { // caso normale if ( aInfo2.IciA[0].dU < aInfo2.IciA[1].dU) dU2 = 0.5 * ( aInfo2.IciA[0].dU + aInfo2.IciA[1].dU) ; // a cavallo di fine / inizio else dU2 = aInfo2.IciA[0].dU + SPAN_PARAM ; } return ( dU2 > dU1 + EPS_PARAM) ; } //---------------------------------------------------------------------------- bool SameParamsAB( const ICurveComposite& CCompoA, const IntCrvCrvInfo& Icci1, const ICurveComposite& CCompoB, const IntCrvCrvInfo& Icci2) { int k = ( Icci1.bOverlap ? 1 : 0) ; // del precedente si prende il secondo se overlap if ( fabs( Icci1.IciA[k].dU - Icci2.IciA[0].dU) > 0.1 * SPAN_PARAM && ( ! CCompoA.IsClosed() || fabs( fabs( Icci1.IciA[k].dU - Icci2.IciA[0].dU) - CCompoA.GetCurveNumber()) > 0.1 * SPAN_PARAM)) return false ; if ( fabs( Icci1.IciB[k].dU - Icci2.IciB[0].dU) > 0.1 * SPAN_PARAM && ( ! CCompoB.IsClosed() || fabs( fabs( Icci1.IciB[k].dU - Icci2.IciB[0].dU) - CCompoB.GetCurveNumber()) > 0.1 * SPAN_PARAM)) return false ; return true ; } //---------------------------------------------------------------------------- static void MediaParamPoints( IntCrvInfo& Ici1, IntCrvInfo& Ici2) { // medio i parametri e i punti // per non mediare i parametri tra gli estremi di curva chiusa if ( fabs( Ici1.dU - Ici2.dU) < 0.1 * SPAN_PARAM) { Ici1.dU = 0.5 * ( Ici1.dU + Ici2.dU) ; Ici2.dU = Ici1.dU ; } Ici1.ptI = 0.5 * ( Ici1.ptI + Ici2.ptI) ; Ici2.ptI = Ici1.ptI ; } //---------------------------------------------------------------------------- // Prev della curva B ma tenendo conto della direzione di A // => se controverse va preso Next static int GetCrvBDirAPrev( IntCrvCrvInfo& Icci) { // non ่ overlap, ่ il prev del primo punto if ( ! Icci.bOverlap) return Icci.IciB[0].nPrevTy ; // ่ overlap equiverso, ่ il prev del primo punto if ( Icci.bCBOverEq) return Icci.IciB[0].nPrevTy ; // ่ overlap controverso, ่ il next del primo punto return Icci.IciB[0].nNextTy ; } //---------------------------------------------------------------------------- // Next della curva B ma tenendo conto della direzione di A // => se controverse va preso Prev static int GetCrvBDirANext( IntCrvCrvInfo& Icci) { // non ่ overlap, ่ il next del primo punto if ( ! Icci.bOverlap) return Icci.IciB[0].nNextTy ; // ่ overlap equiverso, ่ il next del secondo punto if ( Icci.bCBOverEq) return Icci.IciB[1].nNextTy ; // ่ overlap controverso, ่ il prev del secondo punto return Icci.IciB[1].nPrevTy ; } //---------------------------------------------------------------------------- static bool CalcATypeFromDisk( const ICurveComposite& CCompoA, double dUA, ICurve::Side nSideA, const ICurveComposite& CCompoB, double dUB, int& nType) { // devo studiare un intorno dell'intersezione Point3d ptP ; // direzione di arrivo (FROM_MINUS) o partenza (FROM_PLUS) curva A Vector3d vtADir ; if ( ! CCompoA.IsValidParam( dUA, nSideA) || ! CCompoA.GetPointTang( dUA, nSideA, ptP, vtADir)) return false ; if ( nSideA == ICurve::FROM_MINUS) vtADir *= - 1 ; // direzioni di arrivo (prev) e partenza (next) curva B Vector3d vtBpDir ; if ( ! CCompoB.IsValidParam( dUB, ICurve::FROM_MINUS) || ! CCompoB.GetPointTang( dUB, ICurve::FROM_MINUS, ptP, vtBpDir)) return false ; vtBpDir *= - 1 ; Vector3d vtBnDir ; if ( ! CCompoB.IsValidParam( dUB, ICurve::FROM_PLUS) || ! CCompoB.GetPointTang( dUB, ICurve::FROM_PLUS, ptP, vtBnDir)) return false ; // angolo del versore DirA rispetto a DirBn double dAngADeg ; if ( ! vtBnDir.GetAngleXY( vtADir, dAngADeg)) return false ; if ( dAngADeg < 0) dAngADeg += ANG_FULL ; // angolo del versore DirBp rispetto a DirBn double dAngBpDeg ; if ( ! vtBnDir.GetAngleXY( vtBpDir, dAngBpDeg)) return false ; if ( dAngBpDeg < 0) dAngBpDeg += ANG_FULL ; // se l'angolo di DirA ่ compreso tra DirBn e DirBp (muovendosi in senso CCW) allora ่ IN, altrimenti OUT if ( dAngADeg > 0 && dAngADeg < dAngBpDeg) nType = ICCT_IN ; else nType = ICCT_OUT ; return true ; } //---------------------------------------------------------------------------- IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA, const ICurveComposite& CCompoB) { // Le intersezioni sono calcolate nel piano XY locale. // nessuna intersezione trovata m_bOverlaps = false ; m_nNumInters = 0 ; m_Info.clear() ; // doppio ciclo sulle entitเ delle curve composite // !!! questa parte ่ O(N^2), vanno usate Grid Gerarchiche o BVH per renderla O(N*logN) !!! int nCountA = 0 ; for ( const ICurve* pCrvA = CCompoA.GetFirstCurve() ; pCrvA != nullptr ; pCrvA = CCompoA.GetNextCurve(), ++ nCountA) { int nCountB = 0 ; for ( const ICurve* pCrvB = CCompoB.GetFirstCurve() ; pCrvB != nullptr ; pCrvB = CCompoB.GetNextCurve(), ++ nCountB) { // eseguo l'intersezione di queste curve semplici IntersCurveCurve intCC( *pCrvA, *pCrvB) ; // ne recupero i risultati int nCurrInters = intCC.GetNumInters() ; if ( nCurrInters > 0) { m_nNumInters += nCurrInters ; m_bOverlaps = ( intCC.GetOverlaps() ? true : m_bOverlaps) ; for ( int i = 0 ; i < nCurrInters ; ++ i) { IntCrvCrvInfo aInfo ; intCC.GetIntCrvCrvInfo( i, aInfo) ; aInfo.IciA[0].dU += nCountA ; aInfo.IciB[0].dU += nCountB ; if ( aInfo.bOverlap) { aInfo.IciA[1].dU += nCountA ; aInfo.IciB[1].dU += nCountB ; } m_Info.push_back( aInfo) ; } } } } // ordino le intersezioni secondo l'ordine crescente del parametro della prima curva stable_sort( m_Info.begin(), m_Info.end(), SortGreater) ; // sistemazione di intersezioni coincidenti for ( int i = 0 ; i < m_nNumInters ; ++ i) { for ( int j = 0 ; j < m_nNumInters ; ++ j) { // se i due indici coincidono, passo oltre if ( i == j) continue ; // calcolo sottoindici int ki = 0 ; // del successivo si prende sempre il primo int kj = ( m_Info[j].bOverlap ? 1 : 0) ; // del precedente si prende il secondo se overlap // verifico se precedente e corrente si riferiscono alla stessa intersezione (10 * EPS_SMALL) if ( SqDist( m_Info[i].IciA[ki].ptI, m_Info[j].IciA[kj].ptI) < ( 100 * EPS_SMALL * EPS_SMALL) && SqDist( m_Info[i].IciB[ki].ptI, m_Info[j].IciB[kj].ptI) < ( 100 * EPS_SMALL * EPS_SMALL) && SameParamsAB( CCompoA, m_Info[j], CCompoB, m_Info[i])) { // caso DET-NULL -> NULL-DET per prima curva if ( m_Info[j].IciA[kj].nPrevTy != ICCT_NULL && m_Info[j].IciA[kj].nNextTy == ICCT_NULL && m_Info[i].IciA[ki].nPrevTy == ICCT_NULL && m_Info[i].IciA[ki].nNextTy != ICCT_NULL) { // per la prima curva tengo i determinati m_Info[i].IciA[ki].nPrevTy = m_Info[j].IciA[kj].nPrevTy ; m_Info[j].IciA[kj].nNextTy = m_Info[i].IciA[ki].nNextTy ; // se overlap equiverso if ( m_Info[i].bOverlap && m_Info[i].bCBOverEq) { // per la seconda curva ogni sottotipo ่ il duale di quello della prima m_Info[i].IciB[ki].nPrevTy = GetDualIcct( m_Info[i].IciA[ki].nPrevTy) ; m_Info[i].IciB[ki].nNextTy = GetDualIcct( m_Info[i].IciA[ki].nNextTy) ; } // se altrimenti overlap controverso else if ( m_Info[i].bOverlap && ! m_Info[i].bCBOverEq) { // per la seconda curva ogni sottotipo ่ come quello della prima ma in posizione invertita m_Info[i].IciB[ki].nPrevTy = m_Info[i].IciA[ki].nNextTy ; m_Info[i].IciB[ki].nNextTy = m_Info[i].IciA[ki].nPrevTy ; } // se overlap equiverso if ( m_Info[j].bOverlap && m_Info[j].bCBOverEq) { m_Info[j].IciB[kj].nPrevTy = GetDualIcct( m_Info[i].IciA[ki].nPrevTy) ; m_Info[j].IciB[kj].nNextTy = GetDualIcct( m_Info[i].IciA[ki].nNextTy) ; } // se altrimenti overlap controverso else if ( m_Info[j].bOverlap && ! m_Info[j].bCBOverEq) { m_Info[j].IciB[kj].nPrevTy = m_Info[i].IciA[ki].nNextTy ; m_Info[j].IciB[kj].nNextTy = m_Info[i].IciA[ki].nPrevTy ; } // medio parametri e punti separatamente per le due curve MediaParamPoints( m_Info[i].IciA[ki], m_Info[j].IciA[kj]) ; MediaParamPoints( m_Info[i].IciB[ki], m_Info[j].IciB[kj]) ; // se entrambi overlap non cancello if ( m_Info[j].bOverlap && m_Info[i].bOverlap) continue ; // cancello un singolo if ( m_Info[i].bOverlap) { EraseOtherInfo( i, j) ; } else { EraseCurrentInfo( i, j) ; break ; } } // caso NULL-DET -> DET-NULL per prima curva (possibile su inizio/fine di curva chiusa) else if ( m_Info[j].IciA[kj].nPrevTy == ICCT_NULL && m_Info[j].IciA[kj].nNextTy != ICCT_NULL && m_Info[i].IciA[ki].nPrevTy != ICCT_NULL && m_Info[i].IciA[ki].nNextTy == ICCT_NULL) { // per la prima curva tengo i determinati m_Info[i].IciA[ki].nNextTy = m_Info[j].IciA[kj].nNextTy ; m_Info[j].IciA[kj].nPrevTy = m_Info[i].IciA[ki].nPrevTy ; // se overlap equiverso if ( m_Info[i].bOverlap && m_Info[i].bCBOverEq) { // per la seconda curva ogni sottotipo ่ il duale di quello della prima m_Info[i].IciB[ki].nPrevTy = GetDualIcct( m_Info[i].IciA[ki].nPrevTy) ; m_Info[i].IciB[ki].nNextTy = GetDualIcct( m_Info[i].IciA[ki].nNextTy) ; } // se altrimenti overlap controverso else if ( m_Info[i].bOverlap && ! m_Info[i].bCBOverEq) { // per la seconda curva ogni sottotipo ่ come quello della prima ma in posizione scambiata m_Info[i].IciB[ki].nPrevTy = m_Info[i].IciA[ki].nNextTy ; m_Info[i].IciB[ki].nNextTy = m_Info[i].IciA[ki].nPrevTy ; } // se overlap equiverso if ( m_Info[j].bOverlap && m_Info[j].bCBOverEq) { // per la seconda curva ogni sottotipo ่ il duale di quello della prima m_Info[j].IciB[kj].nPrevTy = GetDualIcct( m_Info[i].IciA[ki].nPrevTy) ; m_Info[j].IciB[kj].nNextTy = GetDualIcct( m_Info[i].IciA[ki].nNextTy) ; } // se altrimenti overlap controverso else if ( m_Info[i].bOverlap && ! m_Info[i].bCBOverEq) { // per la seconda curva ogni sottotipo ่ come quello della prima ma in posizione scambiata m_Info[j].IciB[kj].nPrevTy = m_Info[i].IciA[ki].nNextTy ; m_Info[j].IciB[kj].nNextTy = m_Info[i].IciA[ki].nPrevTy ; } // medio parametri e punti separatamente per le due curve MediaParamPoints( m_Info[i].IciA[ki], m_Info[j].IciA[kj]) ; MediaParamPoints( m_Info[i].IciB[ki], m_Info[j].IciB[kj]) ; // se entrambi overlap non cancello if ( m_Info[j].bOverlap && m_Info[i].bOverlap) continue ; // cancello un singolo if ( m_Info[i].bOverlap) { EraseOtherInfo( i, j) ; } else { EraseCurrentInfo( i, j) ; break ; } } // caso DET-NULL -> NULL-DET per seconda curva else if ( m_Info[j].IciB[kj].nPrevTy != ICCT_NULL && m_Info[j].IciB[kj].nNextTy == ICCT_NULL && m_Info[i].IciB[ki].nPrevTy == ICCT_NULL && m_Info[i].IciB[ki].nNextTy != ICCT_NULL) { // per la seconda curva tengo i determinati m_Info[i].IciB[ki].nPrevTy = m_Info[j].IciB[kj].nPrevTy ; m_Info[j].IciB[kj].nNextTy = m_Info[i].IciB[ki].nNextTy ; // se overlap equiverso if ( m_Info[i].bOverlap && m_Info[i].bCBOverEq) { // per la prima curva ogni sottotipo ่ il duale di quello della seconda m_Info[i].IciA[ki].nPrevTy = GetDualIcct( m_Info[i].IciB[ki].nPrevTy) ; m_Info[i].IciA[ki].nNextTy = GetDualIcct( m_Info[i].IciB[ki].nNextTy) ; } // se altrimenti overlap controverso else if ( m_Info[i].bOverlap && ! m_Info[i].bCBOverEq) { // per la prima curva ogni sottotipo ่ come quello della seconda ma in posizione scambiata m_Info[i].IciA[ki].nPrevTy = m_Info[i].IciB[ki].nNextTy ; m_Info[i].IciA[ki].nNextTy = m_Info[i].IciB[ki].nPrevTy ; } // se overlap equiverso if ( m_Info[j].bOverlap && m_Info[j].bCBOverEq) { // per la prima curva ogni sottotipo ่ il duale di quello della seconda m_Info[j].IciA[kj].nPrevTy = GetDualIcct( m_Info[i].IciB[ki].nPrevTy) ; m_Info[j].IciA[kj].nNextTy = GetDualIcct( m_Info[i].IciB[ki].nNextTy) ; } // se altrimenti overlap controverso else if ( m_Info[j].bOverlap && ! m_Info[j].bCBOverEq) { // per la prima curva ogni sottotipo ่ come quello della seconda ma in posizione scambiata m_Info[j].IciA[kj].nPrevTy = m_Info[i].IciB[ki].nNextTy ; m_Info[j].IciA[kj].nNextTy = m_Info[i].IciB[ki].nPrevTy ; } // medio parametri e punti separatamente per le due curve MediaParamPoints( m_Info[i].IciA[ki], m_Info[j].IciA[kj]) ; MediaParamPoints( m_Info[i].IciB[ki], m_Info[j].IciB[kj]) ; // se entrambi overlap non cancello if ( m_Info[j].bOverlap && m_Info[i].bOverlap) continue ; // cancello un singolo if ( m_Info[i].bOverlap) { EraseOtherInfo( i, j) ; } else { EraseCurrentInfo( i, j) ; break ; } } // caso NULL-DET -> DET-NULL per seconda curva (possibile su inizio/fine di curva chiusa) else if ( m_Info[j].IciB[kj].nPrevTy == ICCT_NULL && m_Info[j].IciB[kj].nNextTy != ICCT_NULL && m_Info[i].IciB[ki].nPrevTy != ICCT_NULL && m_Info[i].IciB[ki].nNextTy == ICCT_NULL) { // per la seconda curva tengo i determinati m_Info[i].IciB[ki].nNextTy = m_Info[j].IciB[kj].nNextTy ; m_Info[j].IciB[kj].nPrevTy = m_Info[i].IciB[ki].nPrevTy ; // se overlap equiverso if ( m_Info[i].bOverlap && m_Info[i].bCBOverEq) { // per la prima curva ogni sottotipo ่ il duale di quello della seconda m_Info[i].IciA[ki].nPrevTy = GetDualIcct( m_Info[i].IciB[ki].nPrevTy) ; m_Info[i].IciA[ki].nNextTy = GetDualIcct( m_Info[i].IciB[ki].nNextTy) ; } // se altrimenti overlap controverso else if ( m_Info[i].bOverlap && ! m_Info[i].bCBOverEq) { // per la prima curva ogni sottotipo ่ come quello della seconda ma in posizione scambiata m_Info[i].IciA[ki].nPrevTy = m_Info[i].IciB[ki].nNextTy ; m_Info[i].IciA[ki].nNextTy = m_Info[i].IciB[ki].nPrevTy ; } // se overlap equiverso if ( m_Info[j].bOverlap && m_Info[j].bCBOverEq) { // per la prima curva ogni sottotipo ่ il duale di quello della seconda m_Info[j].IciA[kj].nPrevTy = GetDualIcct( m_Info[i].IciB[ki].nPrevTy) ; m_Info[j].IciA[kj].nNextTy = GetDualIcct( m_Info[i].IciB[ki].nNextTy) ; } // se altrimenti overlap controverso else if ( m_Info[j].bOverlap && ! m_Info[j].bCBOverEq) { // per la prima curva ogni sottotipo ่ come quello della seconda ma in posizione scambiata m_Info[j].IciA[kj].nPrevTy = m_Info[i].IciB[ki].nNextTy ; m_Info[j].IciA[kj].nNextTy = m_Info[i].IciB[ki].nPrevTy ; } // medio parametri e punti separatamente per le due curve MediaParamPoints( m_Info[i].IciA[ki], m_Info[j].IciA[kj]) ; MediaParamPoints( m_Info[i].IciB[ki], m_Info[j].IciB[kj]) ; // se entrambi overlap non cancello if ( m_Info[j].bOverlap && m_Info[i].bOverlap) continue ; // cancello un singolo if ( m_Info[i].bOverlap) { EraseOtherInfo( i, j) ; } else { EraseCurrentInfo( i, j) ; break ; } } // caso NULL-NULL per corrente di prima curva else if ( m_Info[i].IciA[ki].nPrevTy == ICCT_NULL && m_Info[i].IciA[ki].nNextTy == ICCT_NULL) { // cancello l'intersezione corrente (non aggiunge nulla rispetto alla precedente) EraseCurrentInfo( i, j) ; break ; } // caso NULL-NULL per precedente di prima curva else if ( m_Info[j].IciA[kj].nPrevTy == ICCT_NULL && m_Info[j].IciA[kj].nNextTy == ICCT_NULL) { // cancello l'intersezione precedente (non aggiunge nulla rispetto alla corrente) EraseOtherInfo( i, j) ; } } } } // verifico se sono rimaste delle intersezioni di tipo non definito e cerco di risolverle for ( int i = 0 ; i < m_nNumInters ; ++ i) { // in assenza di overlap if ( ! m_Info[i].bOverlap) { // se il tipo di accostamento per la curva A non ่ definito if ( m_Info[i].IciA[0].nPrevTy == ICCT_NULL) { // devo studiare un intorno dell'intersezione int nType ; if ( ! CalcATypeFromDisk( CCompoA, m_Info[i].IciA[0].dU, ICurve::FROM_MINUS, CCompoB, m_Info[i].IciB[0].dU, nType)) continue ; // aggiorno il tipo di accostamento della curva A alla curva B m_Info[i].IciA[0].nPrevTy = nType ; } // se il tipo di accostamento per la curva B non ่ definito if ( m_Info[i].IciB[0].nPrevTy == ICCT_NULL) { // devo studiare un intorno dell'intersezione int nType ; if ( ! CalcATypeFromDisk( CCompoB, m_Info[i].IciB[0].dU, ICurve::FROM_MINUS, CCompoA, m_Info[i].IciA[0].dU, nType)) continue ; // aggiorno il tipo di accostamento della curva B alla curva A m_Info[i].IciB[0].nPrevTy = nType ; } // se il tipo di allontanamento per la curva A non ่ definito if ( m_Info[i].IciA[0].nNextTy == ICCT_NULL) { // devo studiare un intorno dell'intersezione int nType ; if ( ! CalcATypeFromDisk( CCompoA, m_Info[i].IciA[0].dU, ICurve::FROM_PLUS, CCompoB, m_Info[i].IciB[0].dU, nType)) continue ; // aggiorno il tipo di allontanamento della curva A dalla curva B m_Info[i].IciA[0].nNextTy = nType ; } // se il tipo di allontanamento per la curva B non ่ definito if ( m_Info[i].IciB[0].nNextTy == ICCT_NULL) { // devo studiare un intorno dell'intersezione int nType ; if ( ! CalcATypeFromDisk( CCompoB, m_Info[i].IciB[0].dU, ICurve::FROM_PLUS, CCompoA, m_Info[i].IciA[0].dU, nType)) continue ; // aggiorno il tipo di allontanamento della curva B dalla curva A m_Info[i].IciB[0].nNextTy = nType ; } } // in presenza di overlap else { // se il tipo di accostamento ่ non definito per la curva A if ( m_Info[i].IciA[0].nPrevTy == ICCT_NULL) { // devo studiare un intorno dell'intersezione int nType ; if ( ! CalcATypeFromDisk( CCompoA, m_Info[i].IciA[0].dU, ICurve::FROM_MINUS, CCompoB, m_Info[i].IciB[0].dU, nType)) continue ; // aggiorno il tipo di accostamento della curva A alla curva B m_Info[i].IciA[0].nPrevTy = nType ; // aggiorno anche il corrispondente tipo sulla curva B if ( m_Info[i].bCBOverEq) m_Info[i].IciB[0].nPrevTy = GetDualIcct( nType) ; else m_Info[i].IciB[0].nNextTy = nType ; } // se il tipo di allontanamento ่ non definito per la curva A if ( m_Info[i].IciA[1].nNextTy == ICCT_NULL) { // devo studiare un intorno dell'intersezione int nType ; if ( ! CalcATypeFromDisk( CCompoA, m_Info[i].IciA[1].dU, ICurve::FROM_PLUS, CCompoB, m_Info[i].IciB[1].dU, nType)) continue ; // aggiorno il tipo di allontanamento della curva A dalla curva B m_Info[i].IciA[1].nNextTy = nType ; // aggiorno anche il corrispondente tipo sulla curva B if ( m_Info[i].bCBOverEq) m_Info[i].IciB[1].nNextTy = GetDualIcct( nType) ; else m_Info[i].IciB[1].nPrevTy = nType ; } } } // verifico se due intersezioni consecutive di tipo overlap si possono ridurre a una sola for ( int i = 0 ; i < m_nNumInters ; ++ i) { // calcolo indice precedente int j = i - 1 ; if ( i == 0) { // se prima curva aperta, salto alla prossima if ( ! CCompoA.IsClosed()) continue ; // ่ chiusa quindi prendo l'ultima j = m_nNumInters - 1 ; } // se i due indici coincidono, c'่ una sola intersezione e posso uscire if ( i == j) break ; // assegno sottoindici (considero solo intersezioni overlap) int ki = 0 ; int kj = 1 ; // verifico se entrambe overlap, la precedente termina con ON e la successiva inizia con ON // sia sulla curva A sia sulla curva B (tenendo conto del senso equiverso/controverso) if ( m_Info[j].bOverlap && m_Info[i].bOverlap && m_Info[j].IciA[kj].nNextTy == ICCT_ON && m_Info[i].IciA[ki].nPrevTy == ICCT_ON && GetCrvBDirANext( m_Info[j]) == ICCT_ON && GetCrvBDirAPrev( m_Info[i]) == ICCT_ON) { // CurvaA : riporto il secondo punto del successivo sul secondo punto del precedente m_Info[j].IciA[kj].dU = m_Info[i].IciA[kj].dU ; m_Info[j].IciA[kj].ptI = m_Info[i].IciA[kj].ptI ; m_Info[j].IciA[kj].nPrevTy = m_Info[i].IciA[kj].nPrevTy ; m_Info[j].IciA[kj].nNextTy = m_Info[i].IciA[kj].nNextTy ; // CurvaB : riporto il secondo punto del successivo sul secondo punto del precedente m_Info[j].IciB[kj].dU = m_Info[i].IciB[kj].dU ; m_Info[j].IciB[kj].ptI = m_Info[i].IciB[kj].ptI ; m_Info[j].IciB[kj].nPrevTy = m_Info[i].IciB[kj].nPrevTy ; m_Info[j].IciB[kj].nNextTy = m_Info[i].IciB[kj].nNextTy ; // cancello il successivo m_Info.erase( m_Info.begin() + i) ; -- i ; -- m_nNumInters ; } } // se ่ rimasta una sola intersezione con overlap anche ad entrambi gli estremi e le curve sono chiuse if ( m_nNumInters == 1 && CCompoA.IsClosed() && CCompoB.IsClosed() && m_Info[0].IciA[0].nPrevTy == ICCT_ON && m_Info[0].IciA[1].nNextTy == ICCT_ON && GetCrvBDirANext( m_Info[0]) == ICCT_ON && GetCrvBDirAPrev( m_Info[0]) == ICCT_ON) { // questa intersezione con overlap deve interessare completamente le due curve double dStart, dEnd ; CCompoA.GetDomain( dStart, dEnd) ; m_Info[0].IciA[0].dU = dStart ; m_Info[0].IciA[1].dU = dEnd ; CCompoB.GetDomain( dStart, dEnd) ; m_Info[0].IciB[0].dU = ( m_Info[0].bCBOverEq ? dStart : dEnd) ; m_Info[0].IciB[1].dU = ( m_Info[0].bCBOverEq ? dEnd : dStart) ; } } //---------------------------------------------------------------------------- bool IntersCrvCompoCrvCompo::EraseCurrentInfo( int& nIndCurr, int& nIndOther) { m_Info.erase( m_Info.begin() + nIndCurr) ; -- nIndCurr ; -- m_nNumInters ; return true ; } //---------------------------------------------------------------------------- bool IntersCrvCompoCrvCompo::EraseOtherInfo( int& nIndCurr, int& nIndOther) { m_Info.erase( m_Info.begin() + nIndOther) ; if ( nIndOther < nIndCurr) -- nIndCurr ; -- nIndOther ; -- m_nNumInters ; return true ; }