EgtGeomKernel 1.5k5 :
- sviluppo linee tangenti e perpendicolari a curve.
This commit is contained in:
@@ -0,0 +1,234 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// 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_BEZ :
|
||||
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_BEZ :
|
||||
return nullptr ;
|
||||
case CRV_COMPO :
|
||||
return nullptr ;
|
||||
default :
|
||||
return nullptr ;
|
||||
}
|
||||
} break ;
|
||||
case CRV_BEZ :
|
||||
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.IsFlat())
|
||||
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.IsFlat() || ! crvArc2.IsFlat())
|
||||
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 ;
|
||||
}
|
||||
Reference in New Issue
Block a user