From 6eb621d1e1c3f3692e0077e22dbee6c40705c4d2 Mon Sep 17 00:00:00 2001 From: Daniele Bariletti Date: Thu, 15 Jan 2026 16:03:29 +0100 Subject: [PATCH] EgtGeomKernel : - nuova versione dell'intersezione linea-linea che richiede revisioni anche delle intersezioni arco-linea e arco-arco. --- IntersLineLine.cpp | 88 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 68 insertions(+), 20 deletions(-) diff --git a/IntersLineLine.cpp b/IntersLineLine.cpp index c87691c..5c5227b 100644 --- a/IntersLineLine.cpp +++ b/IntersLineLine.cpp @@ -14,6 +14,7 @@ //--------------------------- Include ---------------------------------------- #include "stdafx.h" #include "IntersLineLine.h" +#include "/EgtDev/Include/EgtNumUtils.h" #include using namespace std ; @@ -156,9 +157,29 @@ IntersLineLine::IntersFiniteLines( const CurveLine& Line1, const CurveLine& Line double dCrossXY = CrossXY( vtDir1, vtDir2) ; // flag per linee parallele bool bParallel = ( abs( dCrossXY) < SIN_EPS_ANG_ZERO * ( dLen1XY * dLen2XY)) ; - // flag per segmenti che si allontanano significativamente + // flag per segmenti che si allontanano significativamente bool bFarEnds = ( nS1Side != 0 || nE1Side != 0 || nS2Side != 0 || nE2Side != 0) ; - // analisi casi speciali di quasi parallelismo + + // analisi casi speciali di quasi parallelismo + // segmento sovrapposto all'altro + double dDist1, dDist2 ; + if( nS1Side == 0 || nE1Side == 0 || nS1Side == nE1Side) { + dDist1 = CrossXY( ptS1 - ptS2, vtDir2) ; + dDist2 = CrossXY( ptE1 - ptS2, vtDir2) ; + if( abs( dDist1 - dDist2) < EPS_SMALL * dLen2XY) { + bParallel = true ; + bFarEnds = ! ( (nS1Side == 0 && nE1Side == 0) || (nS2Side == 0 && nE2Side == 0)) ; + } + } + else if( nS2Side == 0 || nE2Side == 0 || nS2Side == nE2Side) { + dDist1 = CrossXY( ptS2 - ptS1, vtDir1) ; + dDist2 = CrossXY( ptE2 - ptS1, vtDir1) ; + if( abs( dDist1 - dDist2) < EPS_SMALL * dLen1XY){ + bParallel = true ; + bFarEnds = ! ( (nS1Side == 0 && nE1Side == 0) || (nS2Side == 0 && nE2Side == 0)) ; + } + } + // estremità sovrapposte di poco if ( ! bParallel && abs( dCrossXY) < ( 0.1 * DEGTORAD) * ( dLen1XY * dLen2XY)) { if (( nS1Side == 0 && nS2Side == 0 && ! AreSamePointXYEpsilon( ptS1, ptS2, 2 * EPS_SMALL)) || ( nS1Side == 0 && nE2Side == 0 && ! AreSamePointXYEpsilon( ptS1, ptE2, 2 * EPS_SMALL)) || @@ -174,27 +195,54 @@ IntersLineLine::IntersFiniteLines( const CurveLine& Line1, const CurveLine& Line // posizioni parametriche dell'intersezione sulle linee m_Info.IciA[0].dU = CrossXY( ( ptS2 - ptS1), vtDir2) / dCrossXY ; m_Info.IciB[0].dU = CrossXY( ( ptS2 - ptS1), vtDir1) / dCrossXY ; - // verifica posizione intersezione su prima linea + // verifica posizione intersezione su prima linea int nPos1 = ICurve::PP_NULL ; // fuori - if ( abs( m_Info.IciA[0].dU * dLen1XY) < EPS_SMALL) - nPos1 = ICurve::PP_START ; // vicino a inizio - else if ( abs(( 1 - m_Info.IciA[0].dU) * dLen1XY) < EPS_SMALL) - nPos1 = ICurve::PP_END ; // vicino a fine - else if ( m_Info.IciA[0].dU > 0 && m_Info.IciA[0].dU < 1) - nPos1 = ICurve::PP_MID ; // nell'interno - else - return ; + if ( nS1Side == 0 || nE1Side == 0) { + if( nS1Side == 0) { + nPos1 = ICurve::PP_START ; + m_Info.IciA[0].dU = 0 ; + m_Info.IciB[0].dU = vtDir2 * ( ptS1 - ptS2) / Pow( vtDir2.Len(), 2) ; + } + else { + nPos1 = ICurve::PP_END ; + m_Info.IciA[0].dU = 1 ; + m_Info.IciB[0].dU = vtDir2 * ( ptE1 - ptS2) / Pow( vtDir2.Len(), 2) ; + } + } + else { + if ( abs( m_Info.IciA[0].dU * dLen1XY) < EPS_SMALL) + nPos1 = ICurve::PP_START ; // vicino a inizio + else if ( abs(( 1 - m_Info.IciA[0].dU) * dLen1XY) < EPS_SMALL) + nPos1 = ICurve::PP_END ; // vicino a fine + else if ( m_Info.IciA[0].dU > 0 && m_Info.IciA[0].dU < 1) + nPos1 = ICurve::PP_MID ; // nell'interno + else + return ; + } // verifica posizione intersezione su seconda linea int nPos2 = ICurve::PP_NULL ; // fuori - if ( abs( m_Info.IciB[0].dU * dLen2XY) < EPS_SMALL) - nPos2 = ICurve::PP_START ; // vicino a inizio - else if ( abs(( 1 - m_Info.IciB[0].dU) * dLen2XY) < EPS_SMALL) - nPos2 = ICurve::PP_END ; // vicino a fine - else if ( m_Info.IciB[0].dU > 0 && m_Info.IciB[0].dU < 1) - nPos2 = ICurve::PP_MID ; // nell'interno - else - return ; - // limito i parametri a stare sui segmenti (0...1) + if ( nS2Side == 0 || nE2Side == 0) { + if( nS2Side == 0) { + nPos2 = ICurve::PP_START ; + m_Info.IciB[0].dU = 0 ; + m_Info.IciA[0].dU = vtDir1 * (ptS2 - ptS1) / Pow( vtDir1.Len(), 2) ; + } + else { + nPos2 = ICurve::PP_END ; + m_Info.IciB[0].dU = 1 ; + m_Info.IciA[0].dU = vtDir1 * (ptE2 - ptS1) / Pow( vtDir1.Len(), 2) ; + } + } + else { + if ( abs( m_Info.IciB[0].dU * dLen2XY) < EPS_SMALL) + nPos2 = ICurve::PP_START ; // vicino a inizio + else if ( abs(( 1 - m_Info.IciB[0].dU) * dLen2XY) < EPS_SMALL) + nPos2 = ICurve::PP_END ; // vicino a fine + else if ( m_Info.IciB[0].dU > 0 && m_Info.IciB[0].dU < 1) + nPos2 = ICurve::PP_MID ; // nell'interno + else + return ; + } // limito i parametri a stare sui segmenti (0...1) m_Info.IciA[0].dU = min( max( m_Info.IciA[0].dU, 0.), 1.) ; m_Info.IciB[0].dU = min( max( m_Info.IciB[0].dU, 0.), 1.) ; // calcolo i punti sulle due linee (possono differire in Z)