de34cfb7e8
- sistemate minuscole/maiuscole in #include.
235 lines
9.3 KiB
C++
235 lines
9.3 KiB
C++
//----------------------------------------------------------------------------
|
|
// EgalTech 2013-2014
|
|
//----------------------------------------------------------------------------
|
|
// File : LinePerpTwoCurves.cpp Data : 25.11.14 Versione : 1.5k5
|
|
// Contenuto : Implementazione funzioni per calcolo rette perpendicolari a curve.
|
|
//
|
|
//
|
|
//
|
|
// Modifiche : 25.11.14 DS Creazione modulo.
|
|
//
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
//--------------------------- Include ----------------------------------------
|
|
#include "stdafx.h"
|
|
#include "CurveLine.h"
|
|
#include "CurveArc.h"
|
|
#include "CreateCurveAux.h"
|
|
#include "/EgtDev/Include/EGkLinePerpTwoCurves.h"
|
|
#include "/EgtDev/Include/EGkLinePntPerpCurve.h"
|
|
#include "/EgtDev/Include/EGkDistPointCurve.h"
|
|
#include "/EgtDev/Include/EgtPointerOwner.h"
|
|
|
|
using namespace std ;
|
|
|
|
//----------------------------------------------------------------------------
|
|
static CurveLine* GetLinePerpTwoLines( const CurveLine& crvLine1, const Point3d& ptNear1,
|
|
const CurveLine& crvLine2, const Point3d& ptNear2) ;
|
|
static CurveLine* GetLinePerpLineArc( const CurveLine& crvLine1, const Point3d& ptNear1,
|
|
const CurveArc& crvArc2, const Point3d& ptNear2) ;
|
|
static CurveLine* GetLinePerpTwoArcs( const CurveArc& crvArc1, const Point3d& ptNear1,
|
|
const CurveArc& crvArc2, const Point3d& ptNear2) ;
|
|
static CurveLine* GetLinePerpTwoConcentricArcs( const CurveArc& crvArc1, const Point3d& ptNear1,
|
|
const CurveArc& crvArc2, const Point3d& ptNear2) ;
|
|
|
|
//----------------------------------------------------------------------------
|
|
ICurveLine*
|
|
GetLinePerpTwoCurves( const ICurve& cCrv1, const Point3d& ptNear1,
|
|
const ICurve& cCrv2, const Point3d& ptNear2)
|
|
{
|
|
switch ( cCrv1.GetType()) {
|
|
case CRV_LINE :
|
|
{ const CurveLine& crvLine1 = *GetBasicCurveLine( &cCrv1) ;
|
|
switch ( cCrv2.GetType()) {
|
|
case CRV_LINE :
|
|
{ const CurveLine& crvLine2 = *GetBasicCurveLine( &cCrv2) ;
|
|
return GetLinePerpTwoLines( crvLine1, ptNear1, crvLine2, ptNear2) ; }
|
|
case CRV_ARC :
|
|
{ const CurveArc& crvArc2 = *GetBasicCurveArc( &cCrv2) ;
|
|
return GetLinePerpLineArc( crvLine1, ptNear1, crvArc2, ptNear2) ; }
|
|
case CRV_BEZIER :
|
|
return nullptr ;
|
|
case CRV_COMPO :
|
|
return nullptr ;
|
|
default :
|
|
return nullptr ;
|
|
}
|
|
} break ;
|
|
case CRV_ARC :
|
|
{ const CurveArc& crvArc1 = *GetBasicCurveArc( &cCrv1) ;
|
|
switch ( cCrv2.GetType()) {
|
|
case CRV_LINE :
|
|
{ const CurveLine& crvLine2 = *GetBasicCurveLine( &cCrv2) ;
|
|
CurveLine* pCrvLine = GetLinePerpLineArc( crvLine2, ptNear2, crvArc1, ptNear1) ;
|
|
if ( pCrvLine != nullptr)
|
|
pCrvLine->Invert() ;
|
|
return pCrvLine ; }
|
|
case CRV_ARC :
|
|
{ const CurveArc& crvArc2 = *GetBasicCurveArc( &cCrv2) ;
|
|
return GetLinePerpTwoArcs( crvArc1, ptNear1, crvArc2, ptNear2) ; }
|
|
case CRV_BEZIER :
|
|
return nullptr ;
|
|
case CRV_COMPO :
|
|
return nullptr ;
|
|
default :
|
|
return nullptr ;
|
|
}
|
|
} break ;
|
|
case CRV_BEZIER :
|
|
return nullptr ;
|
|
case CRV_COMPO :
|
|
return nullptr ;
|
|
default :
|
|
return nullptr ;
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
CurveLine*
|
|
GetLinePerpTwoLines( const CurveLine& crvLine1, const Point3d& ptNear1,
|
|
const CurveLine& crvLine2, const Point3d& ptNear2)
|
|
{
|
|
// le due linee devono essere parallele
|
|
Vector3d vtDir1 ;
|
|
if ( ! crvLine1.GetStartDir( vtDir1))
|
|
return nullptr ;
|
|
Vector3d vtDir2 ;
|
|
if ( ! crvLine2.GetStartDir( vtDir2))
|
|
return nullptr ;
|
|
if ( ! AreSameOrOppositeVectorApprox( vtDir1, vtDir2))
|
|
return nullptr ;
|
|
// determino la sovrapposizione longitudinale del secondo segmento sul primo
|
|
double dLen1 ;
|
|
crvLine1.GetLength( dLen1) ;
|
|
double dStartLen = ( crvLine2.GetStart() - crvLine1.GetStart()) * vtDir1 ;
|
|
double dEndLen = ( crvLine2.GetEnd() - crvLine1.GetStart()) * vtDir1 ;
|
|
if ( dStartLen > dEndLen)
|
|
swap( dStartLen, dEndLen) ;
|
|
if ( dStartLen < 0)
|
|
dStartLen = 0 ;
|
|
if ( dEndLen > dLen1)
|
|
dEndLen = dLen1 ;
|
|
// determino la posizione dei punti vicini sull'intervallo ammesso
|
|
double dNear1Len = ( ptNear1 - crvLine1.GetStart()) * vtDir1 ;
|
|
if ( dNear1Len < dStartLen)
|
|
dNear1Len = dStartLen ;
|
|
if ( dNear1Len > dEndLen)
|
|
dNear1Len = dEndLen ;
|
|
double dNear2Len = ( ptNear2 - crvLine1.GetStart()) * vtDir1 ;
|
|
if ( dNear2Len < dStartLen)
|
|
dNear2Len = dStartLen ;
|
|
if ( dNear2Len > dEndLen)
|
|
dNear2Len = dEndLen ;
|
|
// prendo la posizione intermedia
|
|
double dPosLen = 0.5 * ( dNear1Len + dNear2Len) ;
|
|
Point3d ptP1 = crvLine1.GetStart() + vtDir1 * dPosLen ;
|
|
Point3d ptP2 = crvLine2.GetStart() + ( ptP1 - crvLine2.GetStart()) * vtDir2 * vtDir2 ;
|
|
// creo la linea
|
|
PtrOwner<CurveLine> pCrvLine( CreateBasicCurveLine()) ;
|
|
if ( IsNull( pCrvLine))
|
|
return nullptr ;
|
|
// setto la linea
|
|
if ( ! pCrvLine->Set( ptP1, ptP2))
|
|
return nullptr ;
|
|
// la restituisco
|
|
return Release( pCrvLine) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
CurveLine*
|
|
GetLinePerpLineArc( const CurveLine& crvLine1, const Point3d& ptNear1,
|
|
const CurveArc& crvArc2, const Point3d& ptNear2)
|
|
{
|
|
// l'arco deve essere piatto (no elica)
|
|
if ( ! crvArc2.IsPlane())
|
|
return nullptr ;
|
|
// versore della linea
|
|
Vector3d vtDir1 ;
|
|
if ( ! crvLine1.GetStartDir( vtDir1))
|
|
return nullptr ;
|
|
// la linea deve giacere nel piano dell'arco o parallelo
|
|
if ( ! AreOrthoApprox( vtDir1, crvArc2.GetNormVersor()))
|
|
return nullptr ;
|
|
// lunghezza della linea
|
|
double dLen1 ;
|
|
crvLine1.GetLength( dLen1) ;
|
|
// determino la proiezione del centro dell'arco sulla linea e verifico stia sul segmento
|
|
double dCenLen = ( crvArc2.GetCenter() - crvLine1.GetStart()) * vtDir1 ;
|
|
if ( dCenLen < - EPS_ZERO || dCenLen > dLen1 + EPS_ZERO)
|
|
return nullptr ;
|
|
// punto di proiezione
|
|
Point3d ptP1 = crvLine1.GetStart() + vtDir1 * dCenLen ;
|
|
// punto sulla circonferenza (linea e circonferenza possono essere su piani paralleli)
|
|
Vector3d vtDirP = crvArc2.GetCenter() - ptP1 ;
|
|
vtDirP -= vtDirP * crvArc2.GetNormVersor() * crvArc2.GetNormVersor() ;
|
|
if ( ! vtDirP.Normalize()) {
|
|
// il centro è sul segmento, prendo la normale alla retta nel piano dell'arco
|
|
vtDirP = vtDir1 ^ crvArc2.GetNormVersor() ;
|
|
if ( ! vtDirP.Normalize())
|
|
return nullptr ;
|
|
}
|
|
Point3d ptP2 ;
|
|
if ( ! FindPointOnArc( crvArc2, vtDirP, ptNear2, ptP2))
|
|
return nullptr ;
|
|
// creo la linea
|
|
PtrOwner<CurveLine> pCrvLine( CreateBasicCurveLine()) ;
|
|
if ( IsNull( pCrvLine))
|
|
return nullptr ;
|
|
// setto la linea
|
|
if ( ! pCrvLine->Set( ptP1, ptP2))
|
|
return nullptr ;
|
|
// la restituisco
|
|
return Release( pCrvLine) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
CurveLine*
|
|
GetLinePerpTwoArcs( const CurveArc& crvArc1, const Point3d& ptNear1,
|
|
const CurveArc& crvArc2, const Point3d& ptNear2)
|
|
{
|
|
// i due archi devono giacere nello stesso piano o in piani paralleli ed essere piatti
|
|
if ( ! AreSameOrOppositeVectorApprox( crvArc1.GetNormVersor(), crvArc2.GetNormVersor()) ||
|
|
! crvArc1.IsPlane() || ! crvArc2.IsPlane())
|
|
return nullptr ;
|
|
// la linea cercata deve passare per i due centri
|
|
Vector3d vtDirP = crvArc2.GetCenter() - crvArc1.GetCenter() ;
|
|
vtDirP -= vtDirP * crvArc2.GetNormVersor() * crvArc2.GetNormVersor() ;
|
|
if ( ! vtDirP.Normalize())
|
|
return GetLinePerpTwoConcentricArcs( crvArc1, ptNear1, crvArc2, ptNear2) ;
|
|
Point3d ptP1 ;
|
|
if ( ! FindPointOnArc( crvArc1, vtDirP, ptNear1, ptP1))
|
|
return nullptr ;
|
|
Point3d ptP2 ;
|
|
if ( ! FindPointOnArc( crvArc2, vtDirP, ptNear2, ptP2))
|
|
return nullptr ;
|
|
// creo la linea
|
|
PtrOwner<CurveLine> pCrvLine( CreateBasicCurveLine()) ;
|
|
if ( IsNull( pCrvLine))
|
|
return nullptr ;
|
|
// setto la linea
|
|
if ( ! pCrvLine->Set( ptP1, ptP2))
|
|
return nullptr ;
|
|
// la restituisco
|
|
return Release( pCrvLine) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
CurveLine*
|
|
GetLinePerpTwoConcentricArcs( const CurveArc& crvArc1, const Point3d& ptNear1,
|
|
const CurveArc& crvArc2, const Point3d& ptNear2)
|
|
{
|
|
// trovo il punto più vicino a Near2 sul secondo arco
|
|
DistPointCurve dstPtCurve( ptNear2, crvArc2) ;
|
|
Point3d ptP ;
|
|
int nFlag ;
|
|
if ( ! dstPtCurve.GetMinDistPoint( 0, ptP, nFlag))
|
|
return nullptr ;
|
|
// calcolo la linea perpendicolare al primo arco dal punto trovato e la inverto
|
|
CurveLine* pCrvLine = GetBasicCurveLine( GetLinePointPerpCurve( ptP, crvArc1, ptNear1)) ;
|
|
if ( pCrvLine != nullptr)
|
|
pCrvLine->Invert() ;
|
|
// restituisco la linea
|
|
return pCrvLine ;
|
|
}
|