6c14e51ef6
- aggiunte funzioni per circonferenze e archi tangenti.
149 lines
4.5 KiB
C++
149 lines
4.5 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 ( fabs( dDist - dRad) < EPS_SMALL)
|
|
return 0 ;
|
|
// se è minore del raggio, c'è una sola soluzione
|
|
else if ( dDist < dRad) {
|
|
vCenPtg.emplace_back( ptC, ptCen - vtDir * dRad) ;
|
|
return 1 ;
|
|
}
|
|
// 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 ;
|
|
}
|