Files
EgtGeomKernel/CreateCurveAux.cpp
Dario Sassi 64c954ad4b EgtGeomKernel 1.9l4 :
- fabs sostituito da abs
- in Zmap razionalizzazione operazioni taglio spilloni
- in SurfTriMesh UpdateFaceting senza più chiamate recursive.
2018-12-27 11:19:40 +00:00

144 lines
4.3 KiB
C++

//----------------------------------------------------------------------------
// 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 ;
}