//---------------------------------------------------------------------------- // EgalTech 2013-2013 //---------------------------------------------------------------------------- // File : CreateCurveAux.cpp Data : 27.11.14 Versione : 1.5k5 // Contenuto : Implementazione funzioni di utilità per creazione curve. // // // // Modifiche : 27.11.14 DS Creazione modulo. // // //---------------------------------------------------------------------------- //--------------------------- Include ---------------------------------------- #include "stdafx.h" #include "CreateCurveAux.h" using namespace std ; //---------------------------------------------------------------------------- int CalcLinePointTgCircle( const Point3d& ptP, const Point3d& ptCen, double dRad, BIPNTVECTOR& vBiPnt) { // --- si lavora nel piano XY --- // svuoto il vettore dei risultati (sono coppie di punti) vBiPnt.clear() ; // se il raggio è negativo non ci sono soluzioni if ( dRad < - EPS_SMALL) return 0 ; // vettore dal punto al centro nel piano XY e relativa lunghezza/distanza Vector3d vtPC = ptCen - ptP ; vtPC.z = 0 ; double dDist = vtPC.Len() ; // se il raggio è nullo ... if ( dRad < EPS_SMALL) { // se la distanza tra i punti è significativa, c'è una soluzione : la retta per i due punti if ( dDist > EPS_SMALL) { vBiPnt.emplace_back( ptP, ptCen) ; return 1 ; } // altrimenti, nessuna soluzione else return 0 ; } // se la distanza è inferiore o uguale al raggio non ci sono soluzioni (si esclude la retta tg nel punto P) if ( dDist < dRad + EPS_SMALL) return 0 ; // lunghezza delle tangenti double dLen = sqrt( dDist * dDist - dRad * dRad) ; // punto a metà tra i punti di tangenza Point3d ptK = ptP + vtPC * ( dLen * dLen / ( dDist * dDist)) ; // vettore ortogonale Vector3d vtOrtho = vtPC * ( dRad * dLen / ( dDist * dDist)) ; vtOrtho.Rotate( Z_AX, 0, 1) ; // tangente a destra Point3d ptT = ptK + vtOrtho ; ptT.z = ptCen.z ; vBiPnt.emplace_back( ptP, ptT) ; // tangente a sinistra ptT = ptK - vtOrtho ; ptT.z = ptCen.z ; vBiPnt.emplace_back( ptP, ptT) ; return 2 ; } //---------------------------------------------------------------------------- int CalcCircleCenTgCircle( const Point3d& ptC, const Point3d& ptCen, double dRad, BIPNTVECTOR& vCenPtg) { // --- si lavora nel piano XY --- // svuoto il vettore dei risultati (sono coppie centro-punto di tangenza) vCenPtg.clear() ; // se il raggio è negativo non ci sono soluzioni if ( dRad < - EPS_SMALL) return 0 ; // versore e distanza tra i centri nel piano XY Vector3d vtDir = ptCen - ptC ; vtDir.z = 0 ; double dDist = vtDir.Len() ; vtDir /= dDist ; // se il raggio è nullo ... if ( dRad < EPS_SMALL) { // se la distanza tra i punti è significativa, c'è una soluzione if ( dDist > EPS_SMALL) { vCenPtg.emplace_back( ptC, ptCen) ; return 1 ; } // altrimenti, nessuna soluzione else return 0 ; } // se questa distanza è uguale al raggio, non ci sono soluzioni if ( abs( dDist - dRad) < EPS_SMALL) return 0 ; // altrimenti ci sono due soluzioni else { vCenPtg.emplace_back( ptC, ptCen - vtDir * dRad) ; vCenPtg.emplace_back( ptC, ptCen + vtDir * dRad) ; return 2 ; } } //---------------------------------------------------------------------------- bool FindPointOnArc( const CurveArc& crvArc, const Vector3d& vtDirP, const Point3d& ptNear, Point3d& ptP) { // calcolo i due punti e verifico se stanno sull'arco (anche come angolo) Point3d ptPa = crvArc.GetCenter() + vtDirP * crvArc.GetRadius() ; bool bPaOn = crvArc.IsPointOn( ptPa) && crvArc.IsPointInSector( ptPa) ; Point3d ptPb = crvArc.GetCenter() - vtDirP * crvArc.GetRadius() ; bool bPbOn = crvArc.IsPointOn( ptPb) && crvArc.IsPointInSector( ptPb) ; // se nessuno valido if ( ! bPaOn && ! bPbOn) return false ; // altrimenti scelgo if ( ! bPaOn) ptP = ptPb ; else if ( ! bPbOn) ptP = ptPa ; else { if ( SqDist( ptPa, ptNear) <= SqDist( ptPb, ptNear)) ptP = ptPa ; else ptP = ptPb ; } return true ; }