EgtGeomKernel 1.5k5 :

- sviluppo linee tangenti e perpendicolari a curve.
This commit is contained in:
Dario Sassi
2014-12-01 14:48:44 +00:00
parent 8e0616c889
commit 9347e52d18
13 changed files with 1173 additions and 120 deletions
-1
View File
@@ -216,7 +216,6 @@ GetArcPntDirTgArc( const Point3d& ptP, double dDirStartDeg, const ICurveArc& crv
Point3d ptEnd1 ;
bOk1 = bOk1 && pCrv1->GetEndPoint( ptEnd1) && crvArc.IsPointOn( ptEnd1) ;
// calcolo arco spostando il punto iniziale di - raggio in direzione ortogonale
Point3d ptP2 = ptP - vtOrtho * crvArc.GetRadius() ;
PtrOwner<ICurve> pCrv2( GetArc2PD( ptP2, crvArc.GetCenter(), dDirStartDeg)) ;
+101
View File
@@ -0,0 +1,101 @@
//----------------------------------------------------------------------------
// 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.push_back( make_pair( 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.push_back( make_pair( ptP, ptT)) ;
// tangente a sinistra
ptT = ptK - vtOrtho ;
ptT.z = ptCen.z ;
vBiPnt.push_back( make_pair( ptP, ptT)) ;
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
Point3d ptPa = crvArc.GetCenter() + vtDirP * crvArc.GetRadius() ;
bool bPaOn = crvArc.IsPointOn( ptPa) ;
Point3d ptPb = crvArc.GetCenter() - vtDirP * crvArc.GetRadius() ;
bool bPbOn = crvArc.IsPointOn( 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 ;
}
+8 -4
View File
@@ -1,20 +1,24 @@
//----------------------------------------------------------------------------
// EgalTech 2014-2014
//----------------------------------------------------------------------------
// File : LinePntTgCurve.h Data : 10.06.14 Versione : 1.5f3
// Contenuto : Dichiarazione funzioni di base per calcolo rette tangenti a curve.
// File : CreateCurveAux.h Data : 27.11.14 Versione : 1.5k5
// Contenuto : Dichiarazione funzioni di utilità per creazione curve.
//
//
//
// Modifiche : 10.06.14 DS Creazione modulo.
// Modifiche : 27.11.14 DS Creazione modulo.
//
//
//----------------------------------------------------------------------------
#pragma once
#include "CurveLine.h"
#include "CurveArc.h"
#include "/EgtDev/Include/EGkGeoCollection.h"
//----------------------------------------------------------------------------
int CalcLinePointTgCircle( const Point3d& ptP, const Point3d& ptCen, double dRad, BIPNTVECTOR& vBiPnt) ;
bool FindPointOnArc( const CurveArc& crvArc, const Vector3d& vtDirP, const Point3d& ptNear, Point3d& ptP) ;
BIN
View File
Binary file not shown.
+12 -3
View File
@@ -243,6 +243,7 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
<ClCompile Include="BiArcs.cpp" />
<ClCompile Include="ChainCurves.cpp" />
<ClCompile Include="Color.cpp" />
<ClCompile Include="CreateCurveAux.cpp" />
<ClCompile Include="CurveByInterp.cpp" />
<ClCompile Include="DistPointArc.cpp" />
<ClCompile Include="DistPointCrvAux.cpp" />
@@ -277,8 +278,12 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
<ClCompile Include="IntersLineArc.cpp" />
<ClCompile Include="IntersLineLine.cpp" />
<ClCompile Include="IterManager.cpp" />
<ClCompile Include="LinePerpTwoCurves.cpp" />
<ClCompile Include="LinePntMinDistCurve.cpp" />
<ClCompile Include="LinePntPerpCurve.cpp" />
<ClCompile Include="LinePntTgCurve.cpp" />
<ClCompile Include="LineTgTwoArcs.cpp" />
<ClCompile Include="LineTgCurvePerpCurve.cpp" />
<ClCompile Include="LineTgTwoCurves.cpp" />
<ClCompile Include="Material.cpp" />
<ClCompile Include="FontNfe.cpp" />
<ClCompile Include="NgeReader.cpp" />
@@ -335,8 +340,12 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
<ClInclude Include="..\Include\EGkGeoCollection.h" />
<ClInclude Include="..\Include\EGkGeoVector3d.h" />
<ClInclude Include="..\Include\EGkIntersCurveCurve.h" />
<ClInclude Include="..\Include\EGkLinePerpTwoCurves.h" />
<ClInclude Include="..\Include\EGkLinePntMinDistCurve.h" />
<ClInclude Include="..\Include\EGkLinePntPerpCurve.h" />
<ClInclude Include="..\Include\EGkLinePntTgCurve.h" />
<ClInclude Include="..\Include\EGkLineTgTwoArcs.h" />
<ClInclude Include="..\Include\EGkLineTgCurvePerpCurve.h" />
<ClInclude Include="..\Include\EGkLineTgTwoCurves.h" />
<ClInclude Include="..\Include\EGkMaterial.h" />
<ClInclude Include="..\Include\EgkObjGraphics.h" />
<ClInclude Include="..\Include\EGkPlane3d.h" />
@@ -359,6 +368,7 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
<ClInclude Include="..\Include\ENkPolynomial.h" />
<ClInclude Include="BiArcs.h" />
<ClInclude Include="CalcDerivate.h" />
<ClInclude Include="CreateCurveAux.h" />
<ClInclude Include="DistPointArc.h" />
<ClInclude Include="DistPointCrvAux.h" />
<ClInclude Include="DistPointCrvBezier.h" />
@@ -393,7 +403,6 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
<ClInclude Include="IntersLineArc.h" />
<ClInclude Include="IntersLineLine.h" />
<ClInclude Include="IterManager.h" />
<ClInclude Include="LinePntTgCurve.h" />
<ClInclude Include="Material.h" />
<ClInclude Include="FontNfe.h" />
<ClInclude Include="NgeConst.h" />
+36 -9
View File
@@ -183,9 +183,6 @@
<ClCompile Include="FontAux.cpp">
<Filter>File di origine\Gdb</Filter>
</ClCompile>
<ClCompile Include="LineTgTwoArcs.cpp">
<Filter>File di origine\GeoCreate</Filter>
</ClCompile>
<ClCompile Include="LinePntTgCurve.cpp">
<Filter>File di origine\GeoCreate</Filter>
</ClCompile>
@@ -228,6 +225,24 @@
<ClCompile Include="PolyArc.cpp">
<Filter>File di origine\Base</Filter>
</ClCompile>
<ClCompile Include="LineTgTwoCurves.cpp">
<Filter>File di origine\GeoCreate</Filter>
</ClCompile>
<ClCompile Include="LinePntPerpCurve.cpp">
<Filter>File di origine\GeoCreate</Filter>
</ClCompile>
<ClCompile Include="LinePerpTwoCurves.cpp">
<Filter>File di origine\GeoCreate</Filter>
</ClCompile>
<ClCompile Include="LineTgCurvePerpCurve.cpp">
<Filter>File di origine\GeoCreate</Filter>
</ClCompile>
<ClCompile Include="CreateCurveAux.cpp">
<Filter>File di origine\GeoCreate</Filter>
</ClCompile>
<ClCompile Include="LinePntMinDistCurve.cpp">
<Filter>File di origine\GeoCreate</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="stdafx.h">
@@ -365,9 +380,6 @@
<ClInclude Include="FontAux.h">
<Filter>File di intestazione</Filter>
</ClInclude>
<ClInclude Include="LinePntTgCurve.h">
<Filter>File di intestazione</Filter>
</ClInclude>
<ClInclude Include="IntersLineLine.h">
<Filter>File di intestazione</Filter>
</ClInclude>
@@ -485,9 +497,6 @@
<ClInclude Include="..\Include\EGkTriangle3d.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkLineTgTwoArcs.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkMaterial.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
@@ -548,6 +557,24 @@
<ClInclude Include="BiArcs.h">
<Filter>File di intestazione</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkLineTgTwoCurves.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkLinePntPerpCurve.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkLinePerpTwoCurves.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkLineTgCurvePerpCurve.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
<ClInclude Include="CreateCurveAux.h">
<Filter>File di intestazione</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkLinePntMinDistCurve.h">
<Filter>File di intestazione\Include</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="EgtGeomKernel.rc">
+27 -28
View File
@@ -26,7 +26,7 @@
#include "/EgtDev/Include/EgkCurveLine.h"
#include "/EgtDev/Include/EgkCurveAux.h"
#include "/EgtDev/Include/EgkLinePntTgCurve.h"
#include "/EgtDev/Include/EgkLineTgTwoArcs.h"
#include "/EgtDev/Include/EgkLineTgTwoCurves.h"
#include "/EgtDev/Include/EgkCurveArc.h"
#include "/EgtDev/Include/EgkArcXxTgArc.h"
#include "/EgtDev/Include/EgkCurveBezier.h"
@@ -761,61 +761,60 @@ GdbExecutor::CurveLinePointTgCurve( const STRVECTOR& vsParams)
bool
GdbExecutor::CurveLineTgTwoArcs( const STRVECTOR& vsParams)
{
// 6 parametri : Id, IdParent, IdArc1, ptNear1, IdArc2, ptNear2
// 6 parametri : Id, IdParent, IdCrv1, ptNear1, IdCrv2, ptNear2
if ( vsParams.size() != 6)
return false ;
// recupero il riferimento del gruppo destinazione
Frame3d frDest ;
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frDest))
return false ;
// recupero l'identificativo del primo arco
// recupero l'identificativo della prima curva
int nId1 ;
if ( ( nId1 = GetIdParam( vsParams[2])) == CMD_ID_ERROR)
return false ;
// recupero il riferimento del primo arco
Frame3d frArc1 ;
if ( ! m_pGDB->GetGlobFrame( nId1, frArc1))
// recupero il riferimento della prima curva
Frame3d frCrv1 ;
if ( ! m_pGDB->GetGlobFrame( nId1, frCrv1))
return false ;
// recupero il primo arco
const ICurveArc* pArc1 = GetCurveArc( m_pGDB->GetGeoObj( nId1)) ;
if ( pArc1 == nullptr)
// recupero la prima curva
const ICurve* pCrv1 = GetCurve( m_pGDB->GetGeoObj( nId1)) ;
if ( pCrv1 == nullptr)
return false ;
// recupero il primo punto vicino e lo porto nel riferimento del primo arco
// recupero il primo punto vicino e lo porto nel riferimento della prima curva
Point3d ptNear1 ;
if ( ! GetPointParam( vsParams[3], frDest, ptNear1))
return false ;
Point3d ptN1loc = ptNear1 ;
ptN1loc.LocToLoc( frDest, frArc1) ;
// recupero l'identificativo del secondo arco
ptN1loc.LocToLoc( frDest, frCrv1) ;
// recupero l'identificativo della seconda curva
int nId2 ;
if ( ( nId2 = GetIdParam( vsParams[4])) == CMD_ID_ERROR)
return false ;
// recupero il riferimento del secondo arco
Frame3d frArc2 ;
if ( ! m_pGDB->GetGlobFrame( nId2, frArc2))
// recupero il riferimento della seconda curva
Frame3d frCrv2 ;
if ( ! m_pGDB->GetGlobFrame( nId2, frCrv2))
return false ;
// recupero il secondo arco
const ICurveArc* pArc2 = GetCurveArc( m_pGDB->GetGeoObj( nId2)) ;
if ( pArc2 == nullptr)
// recupero la seconda curva
const ICurve* pCrv2 = GetCurve( m_pGDB->GetGeoObj( nId2)) ;
if ( pCrv2 == nullptr)
return false ;
// porto il secondo arco nel riferimento del primo
PtrOwner<ICurveArc> pArc2Loc( CreateCurveArc()) ;
if ( IsNull( pArc2Loc))
// porto la seconda curva nel riferimento della prima
PtrOwner<ICurve> pCrv2Loc( pCrv2->Clone()) ;
if ( IsNull( pCrv2Loc))
return false ;
pArc2Loc->CopyFrom( pArc2) ;
pArc2Loc->LocToLoc( frArc2, frArc1) ;
// recupero il secondo punto vicino e lo porto nel riferimento del primo arco
pCrv2Loc->LocToLoc( frCrv2, frCrv1) ;
// recupero il secondo punto vicino e lo porto nel riferimento della prima curva
Point3d ptNear2 ;
if ( ! GetPointParam( vsParams[5], frDest, ptNear2))
return false ;
Point3d ptN2loc = ptNear2 ;
ptN2loc.LocToLoc( frDest, frArc1) ;
// calcolo la retta tangente ai due archi
ICurveLine* pCrvLine = GetLineTgTwoArcs( *pArc1, ptN1loc, *pArc2, ptN2loc) ;
ptN2loc.LocToLoc( frDest, frCrv1) ;
// calcolo la retta tangente alle due curve
ICurveLine* pCrvLine = GetLineTgTwoCurves( *pCrv1, ptN1loc, *pCrv2, ptN2loc) ;
if ( pCrvLine == nullptr)
return false ;
// porto la linea nel riferimento del gruppo destinazione
pCrvLine->LocToLoc( frArc1, frDest) ;
pCrvLine->LocToLoc( frCrv1, frDest) ;
// inserisco la linea nel DB
return AddGeoObj( vsParams[0], vsParams[1], pCrvLine) ;
}
+234
View File
@@ -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 ;
}
+80
View File
@@ -0,0 +1,80 @@
//----------------------------------------------------------------------------
// EgalTech 2013-2014
//----------------------------------------------------------------------------
// File : LinePntMinDistCurve.cpp Data : 27.11.14 Versione : 1.5k5
// Contenuto : Implementazione funzioni per calcolo rette di minima distanza da curve.
//
//
//
// Modifiche : 25.11.14 DS Creazione modulo.
//
//
//----------------------------------------------------------------------------
//--------------------------- Include ----------------------------------------
#include "stdafx.h"
#include "CurveLine.h"
#include "/EgtDev/Include/EgkLinePntMinDistCurve.h"
#include "/EgtDev/Include/EgkDistPointCurve.h"
#include "/EgtDev/Include/EgtPointerOwner.h"
using namespace std ;
//----------------------------------------------------------------------------
ICurveLine*
GetLinePointMinDistCurve( const Point3d& ptP, const ICurve& cCrv, const Point3d& ptNear)
{
// calcolo i punti a minima distanza
DistPointCurve dstPtCurve( ptP, cCrv) ;
// ciclo su questi punti per trovare il più vicino al desiderato
bool bFound = false ;
double dMinSqDist = INFINITO * INFINITO ;
Point3d ptFoot ;
MinDistPCInfo mdInfo ;
for ( int i = 0 ; dstPtCurve.GetMinDistInfo( i, mdInfo) ; ++ i) {
// verifico punto
double dSqDist = SqDist( mdInfo.ptQ, ptNear) ;
if ( dSqDist < dMinSqDist) {
bFound = true ;
dMinSqDist = dSqDist ;
ptFoot = mdInfo.ptQ ;
}
}
// verifico eventuali tratti continui
for ( int i = 0 ; dstPtCurve.GetMinDistInfo( i, mdInfo) ; ++ i) {
if ( mdInfo.nFlag == MDPCI_START_CONT) {
MinDistPCInfo mdInfo2 ;
if ( dstPtCurve.GetMinDistInfo( i+1, mdInfo2) && mdInfo2.nFlag == MDPCI_END_CONT) {
// copio la curva e la limito al tratto continuo
PtrOwner<ICurve> pCrvLim( cCrv.Clone()) ;
if ( IsNull( pCrvLim) ||
! pCrvLim->TrimStartEndAtParam( mdInfo.dPar, mdInfo2.dPar))
break ;
// trovo il punto del tratto continuo a minima distanza dal punto near
Point3d ptTest ;
int nFlag ;
DistPointCurve dstPtCurve2( ptNear, *pCrvLim) ;
if ( dstPtCurve2.GetMinDistPoint( 0, ptTest, nFlag)) {
double dSqDist = SqDist( ptTest, ptNear) ;
if ( dSqDist < dMinSqDist) {
bFound = true ;
dMinSqDist = dSqDist ;
ptFoot = ptTest ;
}
}
}
}
}
if ( ! bFound)
return nullptr ;
// creo la linea
PtrOwner<CurveLine> pCrvLine( CreateBasicCurveLine()) ;
if ( IsNull( pCrvLine))
return nullptr ;
// setto la linea
if ( ! pCrvLine->Set( ptP, ptFoot))
return nullptr ;
// la restituisco
return Release( pCrvLine) ;
}
+170
View File
@@ -0,0 +1,170 @@
//----------------------------------------------------------------------------
// EgalTech 2013-2014
//----------------------------------------------------------------------------
// File : LinePntPerpCurve.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 "CurveBezier.h"
#include "CurveComposite.h"
#include "CreateCurveAux.h"
#include "GeoConst.h"
#include "/EgtDev/Include/EgkLinePntPerpCurve.h"
#include "/EgtDev/Include/EgkDistPointCurve.h"
#include "/EgtDev/Include/EgtPointerOwner.h"
using namespace std ;
//----------------------------------------------------------------------------
static CurveLine* GetLinePointPerpLine( const Point3d& ptP, const CurveLine& crvLine, const Point3d& ptNear) ;
static CurveLine* GetLinePointPerpArc( const Point3d& ptP, const CurveArc& crvArc, const Point3d& ptNear) ;
static CurveLine* GetLinePointPerpBezier( const Point3d& ptP, const CurveBezier& crvBezier, const Point3d& ptNear) ;
static CurveLine* GetLinePointPerpCompo( const Point3d& ptP, const CurveComposite& crvCompo, const Point3d& ptNear) ;
//----------------------------------------------------------------------------
ICurveLine*
GetLinePointPerpCurve( const Point3d& ptP, const ICurve& cCrv, const Point3d& ptNear)
{
switch ( cCrv.GetType()) {
case CRV_LINE :
{ const CurveLine& crvLine = *GetBasicCurveLine( &cCrv) ;
return GetLinePointPerpLine( ptP, crvLine, ptNear) ; }
case CRV_ARC :
{ const CurveArc& crvArc = *GetBasicCurveArc( &cCrv) ;
return GetLinePointPerpArc( ptP, crvArc, ptNear) ; }
case CRV_BEZ :
{ const CurveBezier& crvBezier = *GetBasicCurveBezier( &cCrv) ;
return GetLinePointPerpBezier( ptP, crvBezier, ptNear) ; }
case CRV_COMPO :
{ const CurveComposite& crvCompo = *GetBasicCurveComposite( &cCrv) ;
return GetLinePointPerpCompo( ptP, crvCompo, ptNear) ; }
default :
return nullptr ;
}
}
//----------------------------------------------------------------------------
CurveLine*
GetLinePointPerpLine( const Point3d& ptP, const CurveLine& crvLine, const Point3d& ptNear)
{
// direzione della linea
Vector3d vtDir ;
if ( ! crvLine.GetStartDir( vtDir))
return nullptr ;
// lunghezza della linea
double dLen ;
if ( ! crvLine.GetLength( dLen))
return nullptr ;
// piede della perpendicolare dal punto alla linea
double dPerpLen = ( ptP - crvLine.GetStart()) * vtDir ;
if ( dPerpLen < - EPS_ZERO || dPerpLen > dLen + EPS_ZERO)
return nullptr ;
if ( dPerpLen < 0)
dPerpLen = 0 ;
else if ( dPerpLen > dLen)
dPerpLen = dLen ;
Point3d ptFoot = crvLine.GetStart() + dPerpLen * vtDir ;
// creo la linea
PtrOwner<CurveLine> pCrvLine( CreateBasicCurveLine()) ;
if ( IsNull( pCrvLine))
return nullptr ;
// costruisco la linea
if ( ! pCrvLine->Set( ptP, ptFoot))
return nullptr ;
// restituisco la linea
return Release( pCrvLine) ;
}
//----------------------------------------------------------------------------
CurveLine*
GetLinePointPerpArc( const Point3d& ptP, const CurveArc& crvArc, const Point3d& ptNear)
{
// l'arco deve essere piatto (no elica)
if ( ! crvArc.IsFlat())
return nullptr ;
// punti sull'arco su direzione della linea dal punto al centro dell'arco
Point3d ptP2 ;
Vector3d vtDirP = crvArc.GetCenter() - ptP ;
vtDirP -= vtDirP * crvArc.GetNormVersor() * crvArc.GetNormVersor() ;
if ( ! vtDirP.Normalize()) {
// il punto è nel centro dell'arco, l'estremo sull'arco dipende solo da Near
DistPointCurve dstPtCurve( ptNear, crvArc) ;
int nFlag ;
if ( ! dstPtCurve.GetMinDistPoint( 0, ptP2, nFlag))
return nullptr ;
}
else {
if ( ! FindPointOnArc( crvArc, vtDirP, ptNear, ptP2))
return nullptr ;
}
// creo la linea
PtrOwner<CurveLine> pCrvLine( CreateBasicCurveLine()) ;
if ( IsNull( pCrvLine))
return nullptr ;
// costruisco la linea
if ( ! pCrvLine->Set( ptP, ptP2))
return nullptr ;
// restituisco la linea
return Release( pCrvLine) ;
}
//----------------------------------------------------------------------------
CurveLine*
GetLinePointPerpBezier( const Point3d& ptP, const CurveBezier& crvBezier, const Point3d& ptNear)
{
// calcolo approssimazione della curva di Bezier con archi e rette
PolyArc PA ;
if ( ! crvBezier.ApproxWithArcs( 10 * EPS_SMALL, ANG_TOL_STD_DEG, PA))
return nullptr ;
// la trasformo in curva composita
PtrOwner<CurveComposite> pCrvCompo( CreateBasicCurveComposite()) ;
if ( IsNull( pCrvCompo) || ! pCrvCompo->FromPolyArc( PA))
return nullptr ;
// calcolo la linea perpendicolare a questa approssimazione
PtrOwner<CurveLine> pCrvLine( GetBasicCurveLine( GetLinePointPerpCurve( ptP, *pCrvCompo, ptNear))) ;
if ( IsNull( pCrvLine))
return nullptr ;
// porto il punto finale della linea esattamente sulla curva di Bezier
DistPointCurve dstPtCurve( pCrvLine->GetEnd(), crvBezier) ;
Point3d ptP2 ;
int nFlag ;
if ( ! dstPtCurve.GetMinDistPoint( 0, ptP2, nFlag) || ! pCrvLine->ModifyEnd( ptP2))
return nullptr ;
// restituisco la linea
return Release( pCrvLine) ;
}
//----------------------------------------------------------------------------
CurveLine*
GetLinePointPerpCompo( const Point3d& ptP, const CurveComposite& crvCompo, const Point3d& ptNear)
{
// ciclo sulla curva composita
double dMinSqDist = INFINITO * INFINITO ;
PtrOwner<CurveLine> pCrvLine ;
for ( const ICurve* pCrv = crvCompo.GetFirstCurve() ;
pCrv != nullptr ;
pCrv = crvCompo.GetNextCurve()) {
// recupero la linea perpendicolare alla curva elementare
PtrOwner<CurveLine> pCrvLtmp( GetBasicCurveLine( GetLinePointPerpCurve( ptP, *pCrv, ptNear))) ;
if ( IsNull( pCrvLtmp))
continue ;
// verifico se è la più vicina al punto desiderato
double dSqDist = SqDist( ptNear, pCrvLtmp->GetEnd()) ;
if ( dSqDist < dMinSqDist) {
dMinSqDist = dSqDist ;
pCrvLine.Set( Release( pCrvLtmp)) ;
}
}
return Release( pCrvLine) ;
}
+97 -63
View File
@@ -13,35 +13,76 @@
//--------------------------- Include ----------------------------------------
#include "stdafx.h"
#include "LinePntTgCurve.h"
#include "/EgtDev/Include/EgkGeoCollection.h"
#include "CurveLine.h"
#include "CurveArc.h"
#include "CurveBezier.h"
#include "CurveComposite.h"
#include "CreateCurveAux.h"
#include "GeoConst.h"
#include "/EgtDev/Include/EgkLinePntTgCurve.h"
#include "/EgtDev/Include/EgkDistPointCurve.h"
#include "/EgtDev/Include/EgtPointerOwner.h"
using namespace std ;
//----------------------------------------------------------------------------
static CurveLine* GetLinePointTgLine( const Point3d& ptP, const CurveLine& crvLine, const Point3d& ptNear) ;
static CurveLine* GetLinePointTgArc( const Point3d& ptP, const CurveArc& crvArc, const Point3d& ptNear) ;
static CurveLine* GetLinePointTgBezier( const Point3d& ptP, const CurveBezier& crvBezier, const Point3d& ptNear) ;
static CurveLine* GetLinePointTgCompo( const Point3d& ptP, const CurveComposite& crvCompo, const Point3d& ptNear) ;
//----------------------------------------------------------------------------
ICurveLine*
GetLinePointTgCurve( const Point3d& ptP, const ICurve& cCrv, const Point3d& ptNear)
{
switch ( cCrv.GetType()) {
case CRV_LINE :
return nullptr ;
{ const CurveLine& crvLine = *GetBasicCurveLine( &cCrv) ;
return GetLinePointTgLine( ptP, crvLine, ptNear) ; }
case CRV_ARC :
{ const ICurveArc& crvArc = *GetCurveArc( &cCrv) ;
{ const CurveArc& crvArc = *GetBasicCurveArc( &cCrv) ;
return GetLinePointTgArc( ptP, crvArc, ptNear) ; }
case CRV_BEZ :
return nullptr ;
{ const CurveBezier& crvBezier = *GetBasicCurveBezier( &cCrv) ;
return GetLinePointTgBezier( ptP, crvBezier, ptNear) ; }
case CRV_COMPO :
return nullptr ;
{ const CurveComposite& crvCompo = *GetBasicCurveComposite( &cCrv) ;
return GetLinePointTgCompo( ptP, crvCompo, ptNear) ; }
default :
return nullptr ;
}
}
//----------------------------------------------------------------------------
ICurveLine*
GetLinePointTgArc( const Point3d& ptP, const ICurveArc& crvArc, const Point3d& ptNear)
CurveLine*
GetLinePointTgLine( const Point3d& ptP, const CurveLine& crvLine, const Point3d& ptNear)
{
// verifico che il punto giaccia sulla linea estesa
DistPointCurve dstPtCurve( ptP, crvLine, false) ;
double dSqDist ;
if ( ! dstPtCurve.GetSqDist( dSqDist) || dSqDist > EPS_SMALL * EPS_SMALL)
return nullptr ;
// recupero il punto sulla linea più vicino al punto near
Point3d ptP2 ;
int nFlag ;
DistPointCurve dstNearCurve( ptNear, crvLine) ;
if ( ! dstNearCurve.GetMinDistPoint( 0, ptP2, nFlag))
return nullptr ;
// creo la linea
PtrOwner<CurveLine> pCrvLine( CreateBasicCurveLine()) ;
if ( IsNull( pCrvLine))
return nullptr ;
// setto la linea
if ( ! pCrvLine->Set( ptP, ptP2))
return nullptr ;
// la restituisco
return Release( pCrvLine) ;
}
//----------------------------------------------------------------------------
CurveLine*
GetLinePointTgArc( const Point3d& ptP, const CurveArc& crvArc, const Point3d& ptNear)
{
// calcolo il riferimento intrinseco dell'arco (DirNorm->Z e DirStart->X)
Frame3d frIntr ;
@@ -91,70 +132,63 @@ GetLinePointTgArc( const Point3d& ptP, const ICurveArc& crvArc, const Point3d& p
}
// creo la linea
PtrOwner<ICurveLine> pCrvLine( CreateCurveLine()) ;
PtrOwner<CurveLine> pCrvLine( CreateBasicCurveLine()) ;
if ( IsNull( pCrvLine))
return nullptr ;
// costruisco la linea corrispondente alla soluzione scelta
if ( pCrvLine->Set( vBiPnt[nIdOk].first, vBiPnt[nIdOk].second))
return Release( pCrvLine) ;
else
if ( ! pCrvLine->Set( vBiPnt[nIdOk].first, vBiPnt[nIdOk].second))
return nullptr ;
// restituisco la linea
return Release( pCrvLine) ;
}
//----------------------------------------------------------------------------
int
CalcLinePointTgCircle( const Point3d& ptP, const Point3d& ptCen, double dRad, BIPNTVECTOR& vBiPnt)
CurveLine*
GetLinePointTgBezier( const Point3d& ptP, const CurveBezier& crvBezier, const Point3d& ptNear)
{
// --- si lavora nel piano XY ---
// calcolo approssimazione della curva di Bezier con archi e rette
PolyArc PA ;
if ( ! crvBezier.ApproxWithArcs( 10 * EPS_SMALL, ANG_TOL_STD_DEG, PA))
return nullptr ;
// la trasformo in curva composita
PtrOwner<CurveComposite> pCrvCompo( CreateBasicCurveComposite()) ;
if ( IsNull( pCrvCompo) || ! pCrvCompo->FromPolyArc( PA))
return nullptr ;
// calcolo la linea tangente a questa approssimazione
PtrOwner<CurveLine> pCrvLine( GetBasicCurveLine( GetLinePointTgCurve( ptP, *pCrvCompo, ptNear))) ;
if ( IsNull( pCrvLine))
return nullptr ;
// porto il punto finale della linea esattamente sulla curva di Bezier
DistPointCurve dstPtCurve( pCrvLine->GetEnd(), crvBezier) ;
Point3d ptP2 ;
int nFlag ;
if ( ! dstPtCurve.GetMinDistPoint( 0, ptP2, nFlag) || ! pCrvLine->ModifyEnd( ptP2))
return nullptr ;
// restituisco la linea
return Release( pCrvLine) ;
}
// 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.push_back( make_pair( ptP, ptCen)) ;
return 1 ;
//----------------------------------------------------------------------------
CurveLine*
GetLinePointTgCompo( const Point3d& ptP, const CurveComposite& crvCompo, const Point3d& ptNear)
{
// ciclo sulla curva composita
double dMinSqDist = INFINITO * INFINITO ;
PtrOwner<CurveLine> pCrvLine ;
for ( const ICurve* pCrv = crvCompo.GetFirstCurve() ;
pCrv != nullptr ;
pCrv = crvCompo.GetNextCurve()) {
// recupero la linea tangente alla curva elementare
PtrOwner<CurveLine> pCrvLtmp( GetBasicCurveLine( GetLinePointTgCurve( ptP, *pCrv, ptNear))) ;
if ( IsNull( pCrvLtmp))
continue ;
// verifico se è la più vicina al punto desiderato
double dSqDist = SqDist( ptNear, pCrvLtmp->GetEnd()) ;
if ( dSqDist < dMinSqDist) {
dMinSqDist = dSqDist ;
pCrvLine.Set( Release( pCrvLtmp)) ;
}
// 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.push_back( make_pair( ptP, ptT)) ;
// tangente a sinistra
ptT = ptK - vtOrtho ;
ptT.z = ptCen.z ;
vBiPnt.push_back( make_pair( ptP, ptT)) ;
return 2 ;
}
return Release( pCrvLine) ;
}
+266
View File
@@ -0,0 +1,266 @@
//----------------------------------------------------------------------------
// EgalTech 2013-2014
//----------------------------------------------------------------------------
// File : LineTgCurvePerpCurve.cpp Data : 27.11.14 Versione : 1.5k5
// Contenuto : Implementazione funzioni per calcolo rette tg e perp. a curve.
//
//
//
// Modifiche : 27.11.14 DS Creazione modulo.
//
//
//----------------------------------------------------------------------------
//--------------------------- Include ----------------------------------------
#include "stdafx.h"
#include "CreateCurveAux.h"
#include "DistPointLine.h"
#include "/EgtDev/Include/EgkLineTgCurvePerpCurve.h"
#include "/EgtDev/Include/EgkLinePntTgCurve.h"
#include "/EgtDev/Include/EgtPointerOwner.h"
using namespace std ;
//----------------------------------------------------------------------------
static CurveLine* GetLineTgLinePerpLine( const CurveLine& crvLine1, const Point3d& ptNear1,
const CurveLine& crvLine2, const Point3d& ptNear2) ;
static CurveLine* GetLineTgLinePerpArc( const CurveLine& crvLine1, const Point3d& ptNear1,
const CurveArc& crvArc2, const Point3d& ptNear2) ;
static CurveLine* GetLineTgArcPerpArc( const CurveArc& crvArc1, const Point3d& ptNear1,
const CurveArc& crvArc2, const Point3d& ptNear2) ;
static CurveLine* GetLineTgArcPerpLine( const CurveArc& crvArc1, const Point3d& ptNear1,
const CurveLine& crvLine2, const Point3d& ptNear2) ;
//----------------------------------------------------------------------------
ICurveLine*
GetLineTgCurvePerpCurve( 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 GetLineTgLinePerpLine( crvLine1, ptNear1, crvLine2, ptNear2) ; }
case CRV_ARC :
{ const CurveArc& crvArc2 = *GetBasicCurveArc( &cCrv2) ;
return GetLineTgLinePerpArc( crvLine1, ptNear1, crvArc2, ptNear2) ; }
return nullptr ;
case CRV_BEZ :
return nullptr ;
case CRV_COMPO :
return nullptr ;
default :
return nullptr ;
}
}
return nullptr ;
case CRV_ARC :
{ const CurveArc& crvArc1 = *GetBasicCurveArc( &cCrv1) ;
switch ( cCrv2.GetType()) {
case CRV_LINE :
{ const CurveLine& crvLine2 = *GetBasicCurveLine( &cCrv2) ;
return GetLineTgArcPerpLine( crvArc1, ptNear1, crvLine2, ptNear2) ; }
case CRV_ARC :
{ const CurveArc& crvArc2 = *GetBasicCurveArc( &cCrv2) ;
return GetLineTgArcPerpArc( crvArc1, ptNear1, crvArc2, ptNear2) ; }
case CRV_BEZ :
return nullptr ;
case CRV_COMPO :
return nullptr ;
default :
return nullptr ;
}
}
case CRV_BEZ :
return nullptr ;
case CRV_COMPO :
return nullptr ;
default :
return nullptr ;
}
}
//----------------------------------------------------------------------------
CurveLine*
GetLineTgLinePerpLine( const CurveLine& crvLine1, const Point3d& ptNear1,
const CurveLine& crvLine2, const Point3d& ptNear2)
{
// versore della prima linea
Vector3d vtDir1 ;
if ( ! crvLine1.GetStartDir( vtDir1))
return nullptr ;
// versore della seconda linea
Vector3d vtDir2 ;
if ( ! crvLine2.GetStartDir( vtDir2))
return nullptr ;
// le due linee devono essere tra loro ortogonali
if ( ! AreOrthoApprox( vtDir1, vtDir2))
return nullptr ;
// determino il piede delle perpendicolare da un estremo della prima linea alla seconda linea
// e verifico stia sul secondo segmento
Point3d ptP2 ;
if ( ! DistPointLine( crvLine1.GetStart(), crvLine2, false).GetMinDistPoint( ptP2) ||
! crvLine2.IsPointOn( ptP2) )
return nullptr ;
// calcolo il punto sulla prima linea più vicino a Near1
Point3d ptP1 ;
if ( ! DistPointLine( ptNear1, crvLine1).GetMinDistPoint( ptP1))
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*
GetLineTgLinePerpArc( 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 ;
// il centro dell'arco deve essere sulla linea ( o la sua proiezione sul piano // arco contenente linea)
Point3d ptCen = crvArc2.GetCenter() ;
ptCen -= ( ptCen - crvLine1.GetStart()) * crvArc2.GetNormVersor() * crvArc2.GetNormVersor() ;
if ( ! DistPointLine( ptCen, crvLine1, false).IsSmall())
return nullptr ;
// calcolo i due punti possibili sulla circonferenza e scelgo il più vicino a Near2
Vector3d vtDirP = crvArc2.GetCenter() - crvLine1.GetStart() ;
vtDirP -= vtDirP * crvArc2.GetNormVersor() * crvArc2.GetNormVersor() ;
if ( ! vtDirP.Normalize())
return nullptr ;
Point3d ptP2 ;
if ( ! FindPointOnArc( crvArc2, vtDirP, ptNear2, ptP2))
return nullptr ;
// calcolo il punto sulla linea più vicino a Near1
Point3d ptP1 ;
if ( ! DistPointLine( ptNear1, crvLine1).GetMinDistPoint( ptP1))
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*
GetLineTgArcPerpArc( 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 ;
// calcolo la retta dal centro del secondo arco tangente al primo arco e la inverto
PtrOwner<CurveLine> pCrvPtA( GetBasicCurveLine( GetLinePointTgCurve( crvArc2.GetCenter(), crvArc1, ptNear1))) ;
if ( ! IsNull( pCrvPtA))
pCrvPtA->Invert() ;
else {
// se il centro del secondo arco sta sul primo arco, la retta si riduce ad un punto...
// (inoltre possono essere su piani paralleli e diversi)
Point3d ptCen = crvArc2.GetCenter() ;
ptCen -= ( ptCen - crvArc1.GetCenter()) * crvArc1.GetNormVersor() * crvArc1.GetNormVersor() ;
if ( crvArc1.IsPointOn( ptCen)) {
// vettore tangente al primo arco nel punto considerato
Vector3d vtTang = ( ptCen - crvArc1.GetCenter()) ^ crvArc1.GetNormVersor() ;
if ( ! vtTang.Normalize())
return nullptr ;
// costruisco la linea tangente
pCrvPtA.Set( CreateBasicCurveLine()) ;
if ( IsNull( pCrvPtA))
return nullptr ;
pCrvPtA->Set( ptCen, ptCen + vtTang) ;
}
else
return nullptr ;
}
// determino le intersezioni della retta con il secondo arco
Vector3d vtDirP = pCrvPtA->GetEnd() - pCrvPtA->GetStart() ;
vtDirP -= vtDirP * crvArc2.GetNormVersor() * crvArc2.GetNormVersor() ;
if ( ! vtDirP.Normalize())
return nullptr ;
Point3d ptP2 ;
if ( ! FindPointOnArc( crvArc2, vtDirP, ptNear2, ptP2))
return nullptr ;
// modifico il punto finale della retta
if ( ! pCrvPtA->ModifyEnd( ptP2))
return nullptr ;
// restituisco la retta
return Release( pCrvPtA) ;
}
//----------------------------------------------------------------------------
CurveLine*
GetLineTgArcPerpLine( const CurveArc& crvArc1, const Point3d& ptNear1,
const CurveLine& crvLine2, const Point3d& ptNear2)
{
// l'arco deve essere piatto (no elica)
if ( ! crvArc1.IsFlat())
return nullptr ;
// versore della linea
Vector3d vtDir2 ;
if ( ! crvLine2.GetStartDir( vtDir2))
return nullptr ;
// la linea deve giacere nel piano dell'arco o parallelo
if ( ! AreOrthoApprox( vtDir2, crvArc1.GetNormVersor()))
return nullptr ;
// determino la proiezione del centro dell'arco sulla linea
Point3d ptCenPro = crvLine2.GetStart() + ( crvArc1.GetCenter() - crvLine2.GetStart()) * vtDir2 * vtDir2 ;
// versore perpendicolare alla direzione tra centro arco e sua proiezione sulla linea
Vector3d vtDirP = ( ptCenPro - crvArc1.GetCenter()) ^ crvArc1.GetNormVersor() ;
if ( ! vtDirP.Normalize())
return nullptr ;
// punti estremi della linea cercata tra arco e linea data
Point3d ptP1a = crvArc1.GetCenter() + vtDirP * crvArc1.GetRadius() ;
Point3d ptP2a = ptCenPro + vtDirP * crvArc1.GetRadius() ;
bool bLaOk = crvArc1.IsPointOn( ptP1a) && crvLine2.IsPointOn( ptP2a) ;
Point3d ptP1b = crvArc1.GetCenter() - vtDirP * crvArc1.GetRadius() ;
Point3d ptP2b = ptCenPro - vtDirP * crvArc1.GetRadius() ;
bool bLbOk = crvArc1.IsPointOn( ptP1b) && crvLine2.IsPointOn( ptP2b) ;
// se nessuna valida
if ( ! bLaOk && ! bLbOk)
return nullptr ;
// altrimenti scelgo
if ( ! bLaOk) {
swap( ptP1a, ptP1b) ;
swap( ptP2a, ptP2b) ;
}
else if ( ! bLbOk)
;
else {
if ( SqDist( ptP1a, ptNear1) + SqDist( ptP2a, ptNear2) >
SqDist( ptP1b, ptNear1) + SqDist( ptP2b, ptNear2)) {
swap( ptP1a, ptP1b) ;
swap( ptP2a, ptP2b) ;
}
}
// creo la linea
PtrOwner<CurveLine> pCrvLine( CreateBasicCurveLine()) ;
if ( IsNull( pCrvLine))
return nullptr ;
// setto la linea
if ( ! pCrvLine->Set( ptP1a, ptP2a))
return nullptr ;
// la restituisco
return Release( pCrvLine) ;
}
+142 -12
View File
@@ -1,8 +1,8 @@
//----------------------------------------------------------------------------
// EgalTech 2013-2014
//----------------------------------------------------------------------------
// File : LineTgArc.cpp Data : 09.06.14 Versione : 1.5f4
// Contenuto : Implementazione funzioni per calcolo rette tangenti a circonferenze
// File : LineTgTwoCurves.cpp Data : 25.11.14 Versione : 1.5k5
// Contenuto : Implementazione funzioni per calcolo rette tangenti a curve.
//
//
//
@@ -13,26 +13,156 @@
//--------------------------- Include ----------------------------------------
#include "stdafx.h"
#include "LinePntTgCurve.h"
#include "CurveArc.h"
#include "/EgtDev/Include/EgkGeoCollection.h"
#include "/EgtDev/Include/EgkLineTgTwoArcs.h"
#include "CreateCurveAux.h"
#include "DistPointLine.h"
#include "/EgtDev/Include/EgkLineTgTwoCurves.h"
#include "/EgtDev/Include/EgtPointerOwner.h"
using namespace std ;
//----------------------------------------------------------------------------
static CurveLine* GetLineTgTwoLines( const CurveLine& crvLine1, const Point3d& ptNear1,
const CurveLine& crvLine2, const Point3d& ptNear2) ;
static CurveLine* GetLineTgLineArc( const CurveLine& crvLine1, const Point3d& ptNear1,
const CurveArc& crvArc2, const Point3d& ptNear2) ;
static CurveLine* GetLineTgTwoArcs( const CurveArc& crvArc1, const Point3d& ptNear1,
const CurveArc& crvArc2, const Point3d& ptNear2) ;
static int CalcLineExtTg2Circles( const Point3d& ptC1, double dRad1, const Point3d& ptC2, double dRad2, BIPNTVECTOR& vBiPnt) ;
static int CalcLineIntTg2Circles( const Point3d& ptC1, double dRad1, const Point3d& ptC2, double dRad2, BIPNTVECTOR& vBiPnt) ;
static int CalcLineTg2Circles( const Point3d& ptC1, double dRad1, const Point3d& ptC2, double dRad2, BIPNTVECTOR& vBiPnt) ;
//----------------------------------------------------------------------------
ICurveLine*
GetLineTgTwoArcs( const ICurveArc& crvArc1, const Point3d& ptNear1,
const ICurveArc& crvArc2, const Point3d& ptNear2)
GetLineTgTwoCurves( const ICurve& cCrv1, const Point3d& ptNear1,
const ICurve& cCrv2, const Point3d& ptNear2)
{
// verifico che i due archi abbiano lo stesso piano intrinseco
if ( ! AreSameOrOppositeVectorApprox( crvArc1.GetNormVersor(), crvArc2.GetNormVersor()))
switch ( cCrv1.GetType()) {
case CRV_LINE :
{ const CurveLine& crvLine1 = *GetBasicCurveLine( &cCrv1) ;
switch ( cCrv2.GetType()) {
case CRV_LINE :
{ const CurveLine& crvLine2 = *GetBasicCurveLine( &cCrv2) ;
return GetLineTgTwoLines( crvLine1, ptNear1, crvLine2, ptNear2) ; }
case CRV_ARC :
{ const CurveArc& crvArc2 = *GetBasicCurveArc( &cCrv2) ;
return GetLineTgLineArc( 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 = GetLineTgLineArc( crvLine2, ptNear2, crvArc1, ptNear1) ;
if ( pCrvLine != nullptr)
pCrvLine->Invert() ;
return pCrvLine ; }
case CRV_ARC :
{ const CurveArc& crvArc2 = *GetBasicCurveArc( &cCrv2) ;
return GetLineTgTwoArcs( crvArc1, ptNear1, crvArc2, ptNear2) ; }
case CRV_BEZ :
return nullptr ;
case CRV_COMPO :
return nullptr ;
default :
return nullptr ;
}
}
case CRV_BEZ :
return nullptr ;
case CRV_COMPO :
return nullptr ;
default :
return nullptr ;
}
}
//----------------------------------------------------------------------------
CurveLine*
GetLineTgTwoLines( const CurveLine& crvLine1, const Point3d& ptNear1,
const CurveLine& crvLine2, const Point3d& ptNear2)
{
// le due linee devono essere allineate ( i punti dell'una devo appartenere all'altra)
if ( ! DistPointLine( crvLine2.GetStart(), crvLine1, false).IsSmall() ||
! DistPointLine( crvLine2.GetEnd(), crvLine1, false).IsSmall())
return nullptr ;
// ricavo i due punti sulle linee più vicini ai rispettivi near
Point3d ptP1 ;
if ( ! DistPointLine( ptNear1, crvLine1).GetMinDistPoint( ptP1))
return nullptr ;
Point3d ptP2 ;
if ( ! DistPointLine( ptNear2, crvLine2).GetMinDistPoint( ptP2))
return nullptr ;
// creo la linea
PtrOwner<CurveLine> pCrvLine( CreateBasicCurveLine()) ;
if ( IsNull( pCrvLine))
return nullptr ;
// costruisco la linea
if ( ! pCrvLine->Set( ptP1, ptP2))
return nullptr ;
// restituisco la linea
return Release( pCrvLine) ;
}
//----------------------------------------------------------------------------
CurveLine*
GetLineTgLineArc( 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 ;
// vettore spostamento dal piano linea parallelo al piano arco a questo
Vector3d vtMove = ( crvArc2.GetCenter() - crvLine1.GetStart()) * crvArc2.GetNormVersor() * crvArc2.GetNormVersor() ;
// sposto il centro sul piano della linea parallelo a quello dell'arco
Point3d ptCen = crvArc2.GetCenter() - vtMove ;
// il centro deve distare dalla linea quanto il raggio
DistPointLine dstPL( ptCen, crvLine1, false) ;
double dDist ;
if ( ! dstPL.GetDist( dDist) || fabs( dDist - crvArc2.GetRadius()) > EPS_SMALL)
return nullptr ;
// sposto il punto sulla circonferenza e verifico appartenga all'arco
Point3d ptP2 ;
dstPL.GetMinDistPoint( ptP2) ;
ptP2 += vtMove ;
if ( ! crvArc2.IsPointOn( ptP2))
return nullptr ;
// punto sulla linea vicino al desiderato
Point3d ptP1 ;
if ( ! DistPointLine( ptNear1, crvLine1).GetMinDistPoint( ptP1))
return nullptr ;
// creo la linea
PtrOwner<CurveLine> pCrvLine( CreateBasicCurveLine()) ;
if ( IsNull( pCrvLine))
return nullptr ;
// costruisco la linea
if ( ! pCrvLine->Set( ptP1, ptP2))
return nullptr ;
// restituisco la linea
return Release( pCrvLine) ;
}
//----------------------------------------------------------------------------
CurveLine*
GetLineTgTwoArcs( const CurveArc& crvArc1, const Point3d& ptNear1,
const CurveArc& crvArc2, const Point3d& ptNear2)
{
// verifico che i due archi abbiano lo stesso piano intrinseco e siano piatti
if ( ! AreSameOrOppositeVectorApprox( crvArc1.GetNormVersor(), crvArc2.GetNormVersor()) ||
! crvArc1.IsFlat() || ! crvArc2.IsFlat())
return nullptr ;
// calcolo il riferimento intrinseco del primo arco (Z->DirNorm e X->DirStart)
@@ -84,7 +214,7 @@ GetLineTgTwoArcs( const ICurveArc& crvArc1, const Point3d& ptNear1,
}
// creo la linea
PtrOwner<ICurveLine> pCrvLine( CreateCurveLine()) ;
PtrOwner<CurveLine> pCrvLine( CreateBasicCurveLine()) ;
if ( IsNull( pCrvLine))
return nullptr ;
@@ -237,4 +367,4 @@ CalcLineTg2Circles( const Point3d& ptC1, double dRad1, const Point3d& ptC2, doub
nSol += CalcLineIntTg2Circles( ptC1, dRad1, ptC2, dRad2, vBiPnt) ;
return nSol ;
}
}