EgtGeomKernel 1.6c2 :
- aggiunte funzioni per circonferenze e archi tangenti.
This commit is contained in:
@@ -0,0 +1,178 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2015-2015
|
||||
//----------------------------------------------------------------------------
|
||||
// File : ArcCenTgCurvePnt.cpp Data : 15.03.15 Versione : 1.6c2
|
||||
// Contenuto : Implementazione funzioni per calcolo arco dati centro,
|
||||
// tangente a curva e punto vicino a finale.
|
||||
//
|
||||
//
|
||||
// Modifiche : 15.03.15 DS Creazione modulo.
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "CurveBezier.h"
|
||||
#include "CurveComposite.h"
|
||||
#include "CreateCurveAux.h"
|
||||
#include "GeoConst.h"
|
||||
#include "/EgtDev/Include/EgkArcCenTgCurvePnt.h"
|
||||
#include "/EgtDev/Include/EgkArcSpecial.h"
|
||||
#include "/EgtDev/Include/EgkCircleCenTgCurve.h"
|
||||
#include "/EgtDev/Include/EgkDistPointCurve.h"
|
||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static CurveArc* GetArcCenTgCurvePnt( const Point3d& ptCen, const ICurve& cCrv, const Point3d& ptNearStart,
|
||||
const Point3d& ptNearEnd, const Vector3d& vtN, Point3d* pPtTg) ;
|
||||
static CurveArc* GetArcCenTgLinePnt( const Point3d& ptCen, const CurveLine& crvLine, const Point3d& ptNearStart,
|
||||
const Point3d& ptNearEnd, const Vector3d& vtN, Point3d* pPtTg) ;
|
||||
static CurveArc* GetArcCenTgArcPnt( const Point3d& ptCen, const CurveArc& crvArc, const Point3d& ptNearStart,
|
||||
const Point3d& ptNearEnd, const Vector3d& vtN, Point3d* pPtTg) ;
|
||||
static CurveArc* GetArcCenTgBezierPnt( const Point3d& ptCen, const CurveBezier& crvBezier, const Point3d& ptNearStart,
|
||||
const Point3d& ptNearEnd, const Vector3d& vtN, Point3d* pPtTg) ;
|
||||
static CurveArc* GetArcCenTgCompoPnt( const Point3d& ptCen, const CurveComposite& crvCompo, const Point3d& ptNearStart,
|
||||
const Point3d& ptNearEnd, const Vector3d& vtN, Point3d* pPtTg) ;
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
ICurveArc*
|
||||
GetArcCenTgCurvePnt( const Point3d& pCen, const ICurve& cCrv, const Point3d& ptNearStart,
|
||||
const Point3d& ptNearEnd, const Vector3d& vtN)
|
||||
{
|
||||
return GetArcCenTgCurvePnt( pCen, cCrv, ptNearStart, ptNearEnd, vtN, nullptr) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
CurveArc*
|
||||
GetArcCenTgCurvePnt( const Point3d& ptCen, const ICurve& cCrv, const Point3d& ptNearStart,
|
||||
const Point3d& ptNearEnd, const Vector3d& vtN, Point3d* pPtTg)
|
||||
{
|
||||
// verifica dei parametri
|
||||
if ( &ptCen == nullptr || &cCrv == nullptr || &ptNearStart == nullptr ||
|
||||
&ptNearEnd == nullptr || &vtN == nullptr)
|
||||
return nullptr ;
|
||||
// eseguo calcoli a seconda della curva tg
|
||||
switch ( cCrv.GetType()) {
|
||||
case CRV_LINE :
|
||||
{ const CurveLine& crvLine = *GetBasicCurveLine( &cCrv) ;
|
||||
return GetArcCenTgLinePnt( ptCen, crvLine, ptNearStart, ptNearEnd, vtN, pPtTg) ; }
|
||||
case CRV_ARC :
|
||||
{ const CurveArc& crvArc = *GetBasicCurveArc( &cCrv) ;
|
||||
return GetArcCenTgArcPnt( ptCen, crvArc, ptNearStart, ptNearEnd, vtN, pPtTg) ; }
|
||||
case CRV_BEZ :
|
||||
{ const CurveBezier& crvBezier = *GetBasicCurveBezier( &cCrv) ;
|
||||
return GetArcCenTgBezierPnt( ptCen, crvBezier, ptNearStart, ptNearEnd, vtN, pPtTg) ; }
|
||||
case CRV_COMPO :
|
||||
{ const CurveComposite& crvCompo = *GetBasicCurveComposite( &cCrv) ;
|
||||
return GetArcCenTgCompoPnt( ptCen, crvCompo, ptNearStart, ptNearEnd, vtN, pPtTg) ; }
|
||||
default :
|
||||
return nullptr ;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
CurveArc* GetArcCenTgLinePnt( const Point3d& ptCen, const CurveLine& crvLine, const Point3d& ptNearStart,
|
||||
const Point3d& ptNearEnd, const Vector3d& vtN, Point3d* pPtTg)
|
||||
{
|
||||
// ricavo circonferenza con medesimo centro e tangente alla stessa linea
|
||||
Point3d ptTg ;
|
||||
PtrOwner<ICurveArc> pCirc( GetCircleCenTgCurve( ptCen, vtN, crvLine, ptNearStart, &ptTg)) ;
|
||||
if ( IsNull( pCirc))
|
||||
return nullptr ;
|
||||
// costruisco l'arco voluto con i dati di quuesta circonferenza
|
||||
PtrOwner<CurveArc> pArc( CreateBasicCurveArc()) ;
|
||||
if ( pArc->SetC2PN( ptCen, ptTg, ptNearEnd, vtN)) {
|
||||
if ( pPtTg != nullptr)
|
||||
*pPtTg = ptTg ;
|
||||
return Release( pArc) ;
|
||||
}
|
||||
else
|
||||
return nullptr ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
CurveArc* GetArcCenTgArcPnt( const Point3d& ptCen, const CurveArc& crvArc, const Point3d& ptNearStart,
|
||||
const Point3d& ptNearEnd, const Vector3d& vtN, Point3d* pPtTg)
|
||||
{
|
||||
// ricavo circonferenza con medesimo centro e tangente allo stesso arco
|
||||
Point3d ptTg ;
|
||||
PtrOwner<ICurveArc> pCirc( GetCircleCenTgCurve( ptCen, vtN, crvArc, ptNearStart, &ptTg)) ;
|
||||
if ( IsNull( pCirc))
|
||||
return nullptr ;
|
||||
// costruisco l'arco voluto con i dati di quuesta circonferenza
|
||||
PtrOwner<CurveArc> pArc( CreateBasicCurveArc()) ;
|
||||
if ( pArc->SetC2PN( ptCen, ptTg, ptNearEnd, vtN)) {
|
||||
if ( pPtTg != nullptr)
|
||||
*pPtTg = ptTg ;
|
||||
return Release( pArc) ;
|
||||
}
|
||||
else
|
||||
return nullptr ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
CurveArc*
|
||||
GetArcCenTgBezierPnt( const Point3d& ptCen, const CurveBezier& crvBezier, const Point3d& ptNearStart,
|
||||
const Point3d& ptNearEnd, const Vector3d& vtN, Point3d* pPtTg)
|
||||
{
|
||||
// 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 circonferenza tangente a questa approssimazione
|
||||
Point3d ptTg ;
|
||||
PtrOwner<CurveArc> pCrvArc( GetBasicCurveArc( GetArcCenTgCurvePnt( ptCen, *pCrvCompo, ptNearStart,
|
||||
ptNearEnd, vtN, &ptTg))) ;
|
||||
if ( IsNull( pCrvArc))
|
||||
return nullptr ;
|
||||
// porto il punto di tangenza della circonferenza esattamente sulla curva di Bezier
|
||||
DistPointCurve dstPtCurve( ptTg, crvBezier) ;
|
||||
Point3d ptTg2 ;
|
||||
int nFlag ;
|
||||
if ( ! dstPtCurve.GetMinDistPoint( 0, ptTg2, nFlag))
|
||||
return nullptr ;
|
||||
// calcolo il nuovo arco
|
||||
if ( ! pCrvArc->SetC2PN( ptCen, ptTg2, ptNearEnd, vtN))
|
||||
return nullptr ;
|
||||
// se richiesto, assegno il punto di tg
|
||||
if ( pPtTg != nullptr)
|
||||
*pPtTg = ptTg2 ;
|
||||
// restituisco la circonferenza
|
||||
return Release( pCrvArc) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
CurveArc* GetArcCenTgCompoPnt( const Point3d& ptCen, const CurveComposite& crvCompo, const Point3d& ptNearStart,
|
||||
const Point3d& ptNearEnd, const Vector3d& vtN, Point3d* pPtTg)
|
||||
{
|
||||
// ciclo sulla curva composita
|
||||
double dMinSqDist = INFINITO * INFINITO ;
|
||||
PtrOwner<CurveArc> pCrvArc ;
|
||||
for ( const ICurve* pCrv = crvCompo.GetFirstCurve() ;
|
||||
pCrv != nullptr ;
|
||||
pCrv = crvCompo.GetNextCurve()) {
|
||||
// recupero la circonferenza tangente alla curva elementare
|
||||
Point3d ptTg ;
|
||||
PtrOwner<CurveArc> pCrvAtmp( GetBasicCurveArc( GetArcCenTgCurvePnt( ptCen, *pCrv, ptNearStart,
|
||||
ptNearEnd, vtN, &ptTg))) ;
|
||||
if ( IsNull( pCrvAtmp))
|
||||
continue ;
|
||||
// verifico se è la più vicina al punto desiderato
|
||||
double dSqDist = SqDist( ptNearStart, ptTg) ;
|
||||
if ( dSqDist < dMinSqDist) {
|
||||
dMinSqDist = dSqDist ;
|
||||
pCrvArc.Set( Release( pCrvAtmp)) ;
|
||||
if ( pPtTg != nullptr)
|
||||
*pPtTg = ptTg ;
|
||||
}
|
||||
}
|
||||
|
||||
return Release( pCrvArc) ;
|
||||
}
|
||||
@@ -0,0 +1,347 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2015-2015
|
||||
//----------------------------------------------------------------------------
|
||||
// File : ArcPntDirTgCurve.cpp Data : 13.03.15 Versione : 1.6c2
|
||||
// Contenuto : Implementazione funzioni per calcolo arco dato punto iniziale
|
||||
// direzione e tangente a curva.
|
||||
//
|
||||
//
|
||||
// Modifiche : 13.03.15 DS Creazione modulo.
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "CurveBezier.h"
|
||||
#include "CurveComposite.h"
|
||||
#include "CreateCurveAux.h"
|
||||
#include "DistPointLine.h"
|
||||
#include "GeoConst.h"
|
||||
#include "/EgtDev/Include/EgkArcPntDirTgCurve.h"
|
||||
#include "/EgtDev/Include/EgkDistPointCurve.h"
|
||||
#include "/EgtDev/Include/EgkArcSpecial.h"
|
||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static ICurve* GetArcPntDirTgCurve( const Point3d& ptP, const Vector3d& vtDir, const ICurve& cCrv,
|
||||
const Point3d& ptNear, const Vector3d& vtN, Point3d* pPtTg) ;
|
||||
static ICurve* GetArcPntDirTgLine( const Point3d& ptP, const Vector3d& vtDir, const CurveLine& crvLine,
|
||||
const Point3d& ptNear, const Vector3d& vtN, Point3d* pPtTg) ;
|
||||
static ICurve* GetArcPntDirTgArc( const Point3d& ptP, const Vector3d& vtDir, const CurveArc& crvArc,
|
||||
const Point3d& ptNear, const Vector3d& vtN, Point3d* pPtTg) ;
|
||||
static ICurve* GetArcPntDirTgBezier( const Point3d& ptP, const Vector3d& vtDir, const CurveBezier& crvBezier,
|
||||
const Point3d& ptNear, const Vector3d& vtN, Point3d* pPtTg) ;
|
||||
static ICurve* GetArcPntDirTgCompo( const Point3d& ptP, const Vector3d& vtDir, const CurveComposite& crvCompo,
|
||||
const Point3d& ptNear, const Vector3d& vtN, Point3d* pPtTg) ;
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
ICurve*
|
||||
GetArcPntDirTgCurve( const Point3d& ptP, const Vector3d& vtDir, const ICurve& cCrv,
|
||||
const Point3d& ptNear, const Vector3d& vtN)
|
||||
{
|
||||
return GetArcPntDirTgCurve( ptP, vtDir, cCrv, ptNear, vtN, nullptr) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
ICurve*
|
||||
GetArcPntDirTgCurve( const Point3d& ptP, const Vector3d& vtDir, const ICurve& cCrv,
|
||||
const Point3d& ptNear, const Vector3d& vtN, Point3d* pPtTg)
|
||||
{
|
||||
// verifica dei parametri
|
||||
if ( &ptP == nullptr || &vtDir == nullptr || &vtN == nullptr || &cCrv == nullptr || &ptNear == nullptr)
|
||||
return nullptr ;
|
||||
// eseguo calcoli a seconda della curva tg
|
||||
switch ( cCrv.GetType()) {
|
||||
case CRV_LINE :
|
||||
{ const CurveLine& crvLine = *GetBasicCurveLine( &cCrv) ;
|
||||
return GetArcPntDirTgLine( ptP, vtDir, crvLine, ptNear, vtN, pPtTg) ; }
|
||||
case CRV_ARC :
|
||||
{ const CurveArc& crvArc = *GetBasicCurveArc( &cCrv) ;
|
||||
return GetArcPntDirTgArc( ptP, vtDir, crvArc, ptNear, vtN, pPtTg) ; }
|
||||
case CRV_BEZ :
|
||||
{ const CurveBezier& crvBezier = *GetBasicCurveBezier( &cCrv) ;
|
||||
return GetArcPntDirTgBezier( ptP, vtDir, crvBezier, ptNear, vtN, pPtTg) ; }
|
||||
case CRV_COMPO :
|
||||
{ const CurveComposite& crvCompo = *GetBasicCurveComposite( &cCrv) ;
|
||||
return GetArcPntDirTgCompo( ptP, vtDir, crvCompo, ptNear, vtN, pPtTg) ; }
|
||||
default :
|
||||
return nullptr ;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
ICurve*
|
||||
GetArcPntDirTgLine( const Point3d& ptP, const Vector3d& vtDir, const CurveLine& crvLine,
|
||||
const Point3d& ptNear, const Vector3d& vtN, Point3d* pPtTg)
|
||||
{
|
||||
// calcolo il riferimento intrinseco dell'arco da creare (DirNorm->Z e DirStart->X)
|
||||
Frame3d frIntr ;
|
||||
if ( ! frIntr.Set( ptP, vtN, vtDir))
|
||||
return nullptr ;
|
||||
|
||||
// porto la linea di tangenza in questo riferimento
|
||||
CurveLine crvLineL = crvLine ;
|
||||
crvLineL.ToLoc( frIntr) ;
|
||||
|
||||
// inclinazione della linea
|
||||
Point3d ptP1 = crvLineL.GetStart() ;
|
||||
Point3d ptP2 = crvLineL.GetEnd() ;
|
||||
// se linea perpendicolare al piano XY
|
||||
if ( AreSamePointXYApprox( ptP1, ptP2)) {
|
||||
Point3d ptTg( ptP1.x, ptP1.y, 0) ;
|
||||
PtrOwner<ICurve> pCrv( GetArc2PD( ORIG, ptTg, 0)) ;
|
||||
if ( ! IsNull( pCrv) && pCrv->ToGlob( frIntr)) {
|
||||
if ( pPtTg != nullptr) {
|
||||
ptTg.ToGlob( frIntr) ;
|
||||
*pPtTg = ptTg ;
|
||||
}
|
||||
return Release( pCrv) ;
|
||||
}
|
||||
else
|
||||
return nullptr ;
|
||||
}
|
||||
// se linea parallela all'asse X
|
||||
else if ( fabs( ptP2.y - ptP1.y) < EPS_SMALL) {
|
||||
Point3d ptTg( 0, ptP1.y, ptP1.z + ( 0 - ptP1.x) * ( ptP2.z - ptP1.z) / ( ptP2.x - ptP1.x)) ;
|
||||
PtrOwner<ICurve> pCrv( GetArc2PD( ORIG, ptTg, 0)) ;
|
||||
if ( ! IsNull( pCrv) && pCrv->ToGlob( frIntr)) {
|
||||
if ( pPtTg != nullptr) {
|
||||
ptTg.ToGlob( frIntr) ;
|
||||
*pPtTg = ptTg ;
|
||||
}
|
||||
return Release( pCrv) ;
|
||||
}
|
||||
else
|
||||
return nullptr ;
|
||||
}
|
||||
// altrimenti linea inclinata
|
||||
else {
|
||||
// intersezione con asse X (linea di direzione nel riferimento intrinseco)
|
||||
double dCoeff = ( 0 - ptP1.y) / ( ptP2.y - ptP1.y) ;
|
||||
Point3d ptInt( ptP1.x + dCoeff * ( ptP2.x - ptP1.x), 0, ptP1.z + dCoeff * ( ptP2.z - ptP1.z)) ;
|
||||
// punto distante da intersezione in XY come intersezione da origine
|
||||
double dLenXY = fabs( ptInt.x) ;
|
||||
Vector3d vtDir = ptP2 - ptP1 ;
|
||||
vtDir.Normalize() ;
|
||||
double dLen = dLenXY * vtDir.Len() / vtDir.LenXY() ;
|
||||
// con segno +
|
||||
Point3d PtTg1 = ptInt + dLen * vtDir ;
|
||||
PtrOwner<ICurve> pCrv1( GetArc2PD( ORIG, PtTg1, 0)) ;
|
||||
bool bOk1 = ( ! IsNull( pCrv1)) ;
|
||||
// porto l'arco nel riferimento locale
|
||||
bOk1 = bOk1 && pCrv1->ToGlob( frIntr) ;
|
||||
// recupero il punto finale (è quello di tangenza)
|
||||
Point3d ptEnd1 ;
|
||||
bOk1 = bOk1 && pCrv1->GetEndPoint( ptEnd1) ;
|
||||
// verifico se il punto di tangenza sta sul segmento
|
||||
bOk1 = bOk1 && crvLine.IsPointOn( ptEnd1) ;
|
||||
// con segno -
|
||||
Point3d PtTg2 = ptInt - dLen * vtDir ;
|
||||
PtrOwner<ICurve> pCrv2( GetArc2PD( ORIG, PtTg2, 0)) ;
|
||||
bool bOk2 = ( ! IsNull( pCrv2)) ;
|
||||
// porto l'arco nel riferimento locale
|
||||
bOk2 = bOk2 && pCrv2->ToGlob( frIntr) ;
|
||||
// recupero il punto finale (è quello di tangenza)
|
||||
Point3d ptEnd2 ;
|
||||
bOk2 = bOk2 && pCrv2->GetEndPoint( ptEnd2) ;
|
||||
// verifico se il punto di tangenza sta sul segmento
|
||||
bOk2 = bOk2 && crvLine.IsPointOn( ptEnd2) ;
|
||||
// se due soluzioni, verifico quale ha il punto di tg più vicino al richiesto
|
||||
if ( bOk1 && bOk2) {
|
||||
if ( SqDist( ptEnd1, ptNear) <= SqDist( ptEnd2, ptNear))
|
||||
bOk2 = false ;
|
||||
else
|
||||
bOk1 = false ;
|
||||
}
|
||||
// restituisco la soluzione
|
||||
if ( bOk1) {
|
||||
if ( pPtTg != nullptr)
|
||||
*pPtTg = ptEnd1 ;
|
||||
return Release( pCrv1) ;
|
||||
}
|
||||
else if ( bOk2) {
|
||||
if ( pPtTg != nullptr)
|
||||
*pPtTg = ptEnd2 ;
|
||||
return Release( pCrv2) ;
|
||||
}
|
||||
else
|
||||
return nullptr ;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
ICurve*
|
||||
GetArcPntDirTgArc( const Point3d& ptP, const Vector3d& vtDir, const CurveArc& crvArc,
|
||||
const Point3d& ptNear, const Vector3d& vtN, Point3d* pPtTg)
|
||||
{
|
||||
// verifico che la normale della circonferenza coincida con quella dell'arco di tg
|
||||
if ( ! AreSameOrOppositeVectorApprox( vtN, crvArc.GetNormVersor()))
|
||||
return nullptr ;
|
||||
|
||||
// calcolo il riferimento intrinseco dell'arco da creare (DirNorm->Z e DirStart->X)
|
||||
Frame3d frIntr ;
|
||||
if ( ! frIntr.Set( ptP, vtN, vtDir))
|
||||
return nullptr ;
|
||||
|
||||
// porto l'arco di tangenza in questo riferimento
|
||||
CurveArc crvArcL = crvArc ;
|
||||
crvArcL.ToLoc( frIntr) ;
|
||||
|
||||
// versore ortogonale alla direzione iniziale (ora si lavora nel piano XY locale)
|
||||
Vector3d vtOrtho = Y_AX ;
|
||||
|
||||
// angolo direzione iniziale
|
||||
bool bOutSide = ( DistXY( ORIG, crvArcL.GetCenter()) >= crvArcL.GetRadius()) ;
|
||||
|
||||
// calcolo arco spostando il punto iniziale di + raggio in direzione ortogonale
|
||||
Point3d ptP1 = ORIG + vtOrtho * crvArcL.GetRadius() ;
|
||||
PtrOwner<ICurve> pCrv1( GetArc2PD( ptP1, crvArcL.GetCenter(), ( bOutSide ? 0 : 180))) ;
|
||||
bool bOk1 = ( ! IsNull( pCrv1)) ;
|
||||
// compenso lo spostamento ( più -> offset a destra)
|
||||
if ( bOk1) {
|
||||
double dOffset = ( bOutSide ? crvArcL.GetRadius() : - crvArcL.GetRadius()) ;
|
||||
if ( pCrv1->GetType() == CRV_ARC)
|
||||
bOk1 = (dynamic_cast<CurveArc*>(Get(pCrv1)))->ExtendedOffset( dOffset) ;
|
||||
else
|
||||
bOk1 = pCrv1->SimpleOffset( dOffset) ;
|
||||
}
|
||||
// porto l'arco nel riferimento locale
|
||||
bOk1 = bOk1 && pCrv1->ToGlob( frIntr) ;
|
||||
// recupero il punto finale (è quello di tangenza)
|
||||
Point3d ptEnd1 ;
|
||||
bOk1 = bOk1 && pCrv1->GetEndPoint( ptEnd1) ;
|
||||
// se l'arco di tangenza ha deltaN, devo considerarne quota parte
|
||||
if ( bOk1 && fabs( crvArc.GetDeltaN()) > EPS_SMALL) {
|
||||
double dAngDeg ;
|
||||
if ( crvArc.CalcPointAngle( ptEnd1, dAngDeg)) {
|
||||
ptEnd1 += crvArc.GetNormVersor() * crvArc.GetDeltaN() * dAngDeg / crvArc.GetAngCenter() ;
|
||||
bOk1 = bOk1 && pCrv1->ModifyEnd( ptEnd1) ;
|
||||
}
|
||||
else
|
||||
bOk1 = false ;
|
||||
}
|
||||
// verifico se il punto di tangenza sta sull'arco
|
||||
else
|
||||
bOk1 = bOk1 && crvArc.IsPointOn( ptEnd1) ;
|
||||
|
||||
// calcolo arco spostando il punto iniziale di - raggio in direzione ortogonale
|
||||
Point3d ptP2 = ORIG - vtOrtho * crvArcL.GetRadius() ;
|
||||
PtrOwner<ICurve> pCrv2( GetArc2PD( ptP2, crvArcL.GetCenter(), ( bOutSide ? 0 : 180))) ;
|
||||
bool bOk2 = ( ! IsNull( pCrv2)) ;
|
||||
// compenso lo spostamento ( meno -> offset a sinistra)
|
||||
if ( bOk2) {
|
||||
double dOffset = ( bOutSide ? - crvArcL.GetRadius() : crvArcL.GetRadius()) ;
|
||||
if ( pCrv2->GetType() == CRV_ARC)
|
||||
bOk2 = (dynamic_cast<CurveArc*>(Get(pCrv2)))->ExtendedOffset( dOffset) ;
|
||||
else
|
||||
bOk2 = pCrv2->SimpleOffset( dOffset) ;
|
||||
}
|
||||
// porto l'arco nel riferimento locale
|
||||
bOk2 = bOk2 && pCrv2->ToGlob( frIntr) ;
|
||||
// recupero il punto finale (è quello di tangenza)
|
||||
Point3d ptEnd2 ;
|
||||
bOk2 = bOk2 && pCrv2->GetEndPoint( ptEnd2) ;
|
||||
// se l'arco di tangenza ha deltaN, devo considerarne quota parte
|
||||
if ( bOk2 && fabs( crvArc.GetDeltaN()) > EPS_SMALL) {
|
||||
double dAngDeg ;
|
||||
if ( crvArc.CalcPointAngle( ptEnd2, dAngDeg)) {
|
||||
ptEnd2 += crvArc.GetNormVersor() * crvArc.GetDeltaN() * dAngDeg / crvArc.GetAngCenter() ;
|
||||
bOk2 = bOk2 && pCrv2->ModifyEnd( ptEnd2) ;
|
||||
}
|
||||
else
|
||||
bOk2 = false ;
|
||||
}
|
||||
// verifico se il punto di tangenza sta sull'arco
|
||||
else
|
||||
bOk2 = bOk2 && crvArc.IsPointOn( ptEnd2) ;
|
||||
|
||||
// se due soluzioni, verifico quale ha il punto di tg più vicino al richiesto
|
||||
if ( bOk1 && bOk2) {
|
||||
if ( SqDist( ptEnd1, ptNear) <= SqDist( ptEnd2, ptNear))
|
||||
bOk2 = false ;
|
||||
else
|
||||
bOk1 = false ;
|
||||
}
|
||||
|
||||
// restituisco la soluzione
|
||||
if ( bOk1) {
|
||||
if ( pPtTg != nullptr)
|
||||
*pPtTg = ptEnd1 ;
|
||||
return Release( pCrv1) ;
|
||||
}
|
||||
else if ( bOk2) {
|
||||
if ( pPtTg != nullptr)
|
||||
*pPtTg = ptEnd2 ;
|
||||
return Release( pCrv2) ;
|
||||
}
|
||||
else
|
||||
return nullptr ;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
ICurve*
|
||||
GetArcPntDirTgBezier( const Point3d& ptP, const Vector3d& vtDir, const CurveBezier& crvBezier,
|
||||
const Point3d& ptNear, const Vector3d& vtN, Point3d* pPtTg)
|
||||
{
|
||||
// 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 circonferenza tangente a questa approssimazione
|
||||
Point3d ptTg ;
|
||||
PtrOwner<ICurve> pCrv( GetCurve( GetArcPntDirTgCurve( ptP, vtDir, *pCrvCompo, ptNear, vtN, &ptTg))) ;
|
||||
if ( IsNull( pCrv))
|
||||
return nullptr ;
|
||||
// porto il punto di tangenza della circonferenza esattamente sulla curva di Bezier
|
||||
DistPointCurve dstPtCurve( ptTg, crvBezier) ;
|
||||
Point3d ptTg2 ;
|
||||
int nFlag ;
|
||||
if ( ! dstPtCurve.GetMinDistPoint( 0, ptTg2, nFlag))
|
||||
return nullptr ;
|
||||
// calcolo il nuovo arco
|
||||
pCrv.Set( GetArc2PVN( ptP, ptTg2, vtDir, vtN)) ;
|
||||
if ( IsNull( pCrv))
|
||||
return nullptr ;
|
||||
// se richiesto, assegno il punto di tg
|
||||
if ( pPtTg != nullptr)
|
||||
*pPtTg = ptTg2 ;
|
||||
// restituisco la circonferenza
|
||||
return Release( pCrv) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
ICurve*
|
||||
GetArcPntDirTgCompo( const Point3d& ptP, const Vector3d& vtDir, const CurveComposite& crvCompo,
|
||||
const Point3d& ptNear, const Vector3d& vtN, Point3d* pPtTg)
|
||||
{
|
||||
// ciclo sulla curva composita
|
||||
double dMinSqDist = INFINITO * INFINITO ;
|
||||
PtrOwner<ICurve> pCrvNew ;
|
||||
for ( const ICurve* pCrv = crvCompo.GetFirstCurve() ;
|
||||
pCrv != nullptr ;
|
||||
pCrv = crvCompo.GetNextCurve()) {
|
||||
// recupero la circonferenza tangente alla curva elementare
|
||||
Point3d ptTg ;
|
||||
PtrOwner<ICurve> pCrvTmp( GetCurve( GetArcPntDirTgCurve( ptP, vtDir, *pCrv, ptNear, vtN, &ptTg))) ;
|
||||
if ( IsNull( pCrvTmp))
|
||||
continue ;
|
||||
// verifico se è la più vicina al punto desiderato
|
||||
double dSqDist = SqDist( ptNear, ptTg) ;
|
||||
if ( dSqDist < dMinSqDist) {
|
||||
dMinSqDist = dSqDist ;
|
||||
pCrvNew.Set( Release( pCrvTmp)) ;
|
||||
if ( pPtTg != nullptr)
|
||||
*pPtTg = ptTg ;
|
||||
}
|
||||
}
|
||||
|
||||
return Release( pCrvNew) ;
|
||||
}
|
||||
+133
@@ -0,0 +1,133 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2014-2015
|
||||
//----------------------------------------------------------------------------
|
||||
// File : ArcSpecial.cpp Data : 15.03.15 Versione : 1.6c2
|
||||
// Contenuto : Implementazione funzioni per calcoli speciali archi.
|
||||
//
|
||||
//
|
||||
//
|
||||
// Modifiche : 12.06.14 DS Creazione modulo.
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "CreateCurveAux.h"
|
||||
#include "/EgtDev/Include/EgkCurveLine.h"
|
||||
#include "/EgtDev/Include/EgkArcSpecial.h"
|
||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||
|
||||
using namespace std ;
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Come la CurveArc::Set2PD, ma se raggio infinito restituisce una retta
|
||||
//----------------------------------------------------------------------------
|
||||
ICurve*
|
||||
GetArc2PD( const Point3d& ptStart, const Point3d& ptEnd, double dDirStartDeg)
|
||||
{
|
||||
// creo l'oggetto arco
|
||||
ICurveArc* pArc = CreateCurveArc() ;
|
||||
if ( pArc == nullptr)
|
||||
return nullptr ;
|
||||
// inizializzo il puntatore a curva con l'arco
|
||||
PtrOwner<ICurve> pCrv( pArc) ;
|
||||
|
||||
// calcolo l'arco, se ok lo restituisco ed esco
|
||||
if ( pArc->Set2PD( ptStart, ptEnd, dDirStartDeg))
|
||||
return Release( pCrv) ;
|
||||
|
||||
// calcolo arco non riuscito, verifico se retta va bene
|
||||
Vector3d vtDiff = ptEnd - ptStart ;
|
||||
vtDiff.z = 0 ;
|
||||
Vector3d vtDir = FromPolar( 1, dDirStartDeg) ;
|
||||
// verifico se i punti sono allineati con la direzione e nel giusto verso
|
||||
if ( fabs( CrossXY( vtDiff, vtDir)) < EPS_SMALL && ScalarXY( vtDiff, vtDir) > EPS_SMALL) {
|
||||
// creo l'oggetto retta
|
||||
ICurveLine* pLine = CreateCurveLine() ;
|
||||
if ( pLine == nullptr)
|
||||
return nullptr ;
|
||||
// inizializzo il puntatore a curva con la retta
|
||||
pCrv.Set( pLine) ;
|
||||
// calcolo retta, se ok la restituisco ed esco
|
||||
if ( pLine->Set( ptStart, ptEnd))
|
||||
return Release( pCrv) ;
|
||||
}
|
||||
|
||||
return nullptr ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Come la CurveArc::Set2PVN, ma se raggio infinito restituisce una retta
|
||||
//----------------------------------------------------------------------------
|
||||
ICurve*
|
||||
GetArc2PVN( const Point3d& ptStart, const Point3d& ptEnd, const Vector3d& vtDirS, const Vector3d& vtN)
|
||||
{
|
||||
// creo l'oggetto arco
|
||||
ICurveArc* pArc = CreateCurveArc() ;
|
||||
if ( pArc == nullptr)
|
||||
return nullptr ;
|
||||
// inizializzo il puntatore a curva con l'arco
|
||||
PtrOwner<ICurve> pCrv( pArc) ;
|
||||
|
||||
// calcolo l'arco, se ok lo restituisco ed esco
|
||||
if ( pArc->Set2PVN( ptStart, ptEnd, vtDirS, vtN))
|
||||
return Release( pCrv) ;
|
||||
|
||||
// calcolo arco non riuscito, verifico se retta va bene
|
||||
Vector3d vtDiff = ptEnd - ptStart ;
|
||||
vtDiff.z = 0 ;
|
||||
// verifico se i punti sono allineati con la direzione e nel giusto verso
|
||||
if ( fabs( CrossXY( vtDiff, vtDirS)) < EPS_SMALL && ScalarXY( vtDiff, vtDirS) > EPS_SMALL) {
|
||||
// creo l'oggetto retta
|
||||
ICurveLine* pLine = CreateCurveLine() ;
|
||||
if ( pLine == nullptr)
|
||||
return nullptr ;
|
||||
// inizializzo il puntatore a curva con la retta
|
||||
pCrv.Set( pLine) ;
|
||||
// calcolo retta, se ok la restituisco ed esco
|
||||
if ( pLine->Set( ptStart, ptEnd))
|
||||
return Release( pCrv) ;
|
||||
}
|
||||
|
||||
return nullptr ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Come la CurveArc::Set3P, ma se raggio infinito restituisce una retta
|
||||
//----------------------------------------------------------------------------
|
||||
ICurve*
|
||||
GetArc3P( const Point3d& ptStart, const Point3d& ptOther, const Point3d& ptEnd, bool bCirc)
|
||||
{
|
||||
// creo l'oggetto arco
|
||||
ICurveArc* pArc = CreateCurveArc() ;
|
||||
if ( pArc == nullptr)
|
||||
return nullptr ;
|
||||
// inizializzo il puntatore a curva con l'arco
|
||||
PtrOwner<ICurve> pCrv( pArc) ;
|
||||
|
||||
// calcolo l'arco, se ok lo restituisco ed esco
|
||||
if ( pArc->Set3P( ptStart, ptOther, ptEnd, bCirc))
|
||||
return Release( pCrv) ;
|
||||
|
||||
// se era richiesta una circonferenza, errore
|
||||
if ( bCirc)
|
||||
return nullptr ;
|
||||
|
||||
// calcolo arco non riuscito, se i punti sono allineati nel giusto verso per essere una retta
|
||||
// verifico se i punti sono allineati nel giusto verso
|
||||
if ( ( ptOther - ptStart) * ( ptEnd - ptOther) > EPS_ZERO) {
|
||||
// creo l'oggetto retta
|
||||
ICurveLine* pLine = CreateCurveLine() ;
|
||||
if ( pLine == nullptr)
|
||||
return nullptr ;
|
||||
// inizializzo il puntatore a curva con la retta
|
||||
pCrv.Set( pLine) ;
|
||||
// calcolo retta, se ok la restituisco ed esco
|
||||
if ( pLine->Set( ptStart, ptEnd))
|
||||
return Release( pCrv) ;
|
||||
}
|
||||
|
||||
return nullptr ;
|
||||
}
|
||||
-291
@@ -1,291 +0,0 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2013-2014
|
||||
//----------------------------------------------------------------------------
|
||||
// File : ArcXxTgArc.cpp Data : 12.06.14 Versione : 1.5f4
|
||||
// Contenuto : Implementazione funzioni per calcolo archi tangenti a archi.
|
||||
//
|
||||
//
|
||||
//
|
||||
// Modifiche : 12.06.14 DS Creazione modulo.
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "/EgtDev/Include/EgkCurveLine.h"
|
||||
#include "/EgtDev/Include/EgkArcXxTgArc.h"
|
||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||
|
||||
using namespace std ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static int CalcCircleCenTgCircle( const Point3d& ptC, const Point3d& ptCen, double dRad, BIPNTVECTOR& vCenPtg) ;
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
ICurveArc*
|
||||
GetCircleCenTgArc( const Point3d& ptCen, const ICurveArc& crvArc, const Point3d& ptNear)
|
||||
{
|
||||
// calcolo il riferimento intrinseco dell'arco (DirNorm->Z e DirStart->X)
|
||||
Frame3d frIntr ;
|
||||
if ( ! frIntr.Set( crvArc.GetCenter(), crvArc.GetNormVersor(), crvArc.GetStartVersor()))
|
||||
return nullptr ;
|
||||
|
||||
// porto il punto nel riferimento intrinseco
|
||||
Point3d ptCLoc = ptCen ;
|
||||
ptCLoc.ToLoc( frIntr) ;
|
||||
|
||||
// calcolo le circonferenze tangenti alla circonferenza
|
||||
BIPNTVECTOR vCenPtg( 2) ;
|
||||
int nSol = CalcCircleCenTgCircle( ptCLoc, ORIG, crvArc.GetRadius(), vCenPtg) ;
|
||||
if ( nSol == 0)
|
||||
return nullptr ;
|
||||
|
||||
// porto i punti nel riferimento standard dell'arco
|
||||
for ( size_t i = 0 ; i < vCenPtg.size() ; ++ i) {
|
||||
vCenPtg[i].first.ToGlob( frIntr) ;
|
||||
vCenPtg[i].second.ToGlob( frIntr) ;
|
||||
}
|
||||
|
||||
// elimino le soluzioni che non stanno sull'arco
|
||||
for ( int i = 1 ; i >= 0 ; -- i) {
|
||||
if ( nSol > i) {
|
||||
if ( ! crvArc.IsPointOn( vCenPtg[i].second)) {
|
||||
-- nSol ;
|
||||
for ( int j = i ; j < nSol ; ++ j)
|
||||
vCenPtg[j] = vCenPtg[j+1] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// se non sono rimaste soluzioni, esco
|
||||
if ( nSol == 0)
|
||||
return nullptr ;
|
||||
|
||||
// scelgo la soluzione più vicina al punto di riferimento
|
||||
int nIdOk = 0 ;
|
||||
double dMinSqDist = INFINITO * INFINITO ;
|
||||
for ( int i = 0 ; i < nSol ; ++ i) {
|
||||
double dSqDist = SqDist( vCenPtg[i].second, ptNear) ;
|
||||
if ( dSqDist < dMinSqDist) {
|
||||
dMinSqDist = dSqDist ;
|
||||
nIdOk = i ;
|
||||
}
|
||||
}
|
||||
|
||||
// creo l'arco
|
||||
PtrOwner<ICurveArc> pCrvArc( CreateCurveArc()) ;
|
||||
if ( IsNull( pCrvArc))
|
||||
return nullptr ;
|
||||
|
||||
// costruisco la circonferenza corrispondente alla soluzione scelta
|
||||
double dRad = DistXY( vCenPtg[nIdOk].first, vCenPtg[nIdOk].second) ;
|
||||
if ( pCrvArc->Set( vCenPtg[nIdOk].first, crvArc.GetNormVersor(), dRad))
|
||||
return Release( pCrvArc) ;
|
||||
else
|
||||
return nullptr ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
ICurveArc*
|
||||
GetArcCenTgArcPnt( const Point3d& ptCen, const ICurveArc& crvArc,
|
||||
const Point3d& ptNearTg, const Point3d& ptNearEnd)
|
||||
{
|
||||
// calcolo il riferimento intrinseco dell'arco (DirNorm->Z e DirStart->X)
|
||||
Frame3d frIntr ;
|
||||
if ( ! frIntr.Set( crvArc.GetCenter(), crvArc.GetNormVersor(), crvArc.GetStartVersor()))
|
||||
return nullptr ;
|
||||
|
||||
// porto il centro nel riferimento intrinseco
|
||||
Point3d ptCLoc = ptCen ;
|
||||
ptCLoc.ToLoc( frIntr) ;
|
||||
|
||||
// calcolo le circonferenze tangenti alla circonferenza
|
||||
BIPNTVECTOR vCenPtg( 2) ;
|
||||
int nSol = CalcCircleCenTgCircle( ptCLoc, ORIG, crvArc.GetRadius(), vCenPtg) ;
|
||||
if ( nSol == 0)
|
||||
return nullptr ;
|
||||
|
||||
// porto i punti nel riferimento standard dell'arco
|
||||
for ( size_t i = 0 ; i < vCenPtg.size() ; ++ i) {
|
||||
vCenPtg[i].first.ToGlob( frIntr) ;
|
||||
vCenPtg[i].second.ToGlob( frIntr) ;
|
||||
}
|
||||
|
||||
// elimino le soluzioni che non stanno sull'arco
|
||||
for ( int i = 1 ; i >= 0 ; -- i) {
|
||||
if ( nSol > i) {
|
||||
if ( ! crvArc.IsPointOn( vCenPtg[i].second)) {
|
||||
-- nSol ;
|
||||
for ( int j = i ; j < nSol ; ++ j)
|
||||
vCenPtg[j] = vCenPtg[j+1] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// se non sono rimaste soluzioni, esco
|
||||
if ( nSol == 0)
|
||||
return nullptr ;
|
||||
|
||||
// scelgo la soluzione più vicina al punto di riferimento
|
||||
int nIdOk = 0 ;
|
||||
double dMinSqDist = INFINITO * INFINITO ;
|
||||
for ( int i = 0 ; i < nSol ; ++ i) {
|
||||
double dSqDist = SqDist( vCenPtg[i].second, ptNearTg) ;
|
||||
if ( dSqDist < dMinSqDist) {
|
||||
dMinSqDist = dSqDist ;
|
||||
nIdOk = i ;
|
||||
}
|
||||
}
|
||||
|
||||
// creo l'arco
|
||||
PtrOwner<ICurveArc> pCrvArc( CreateCurveArc()) ;
|
||||
if ( IsNull( pCrvArc))
|
||||
return nullptr ;
|
||||
|
||||
// posso costruire l'arco solo nel riferimento intrinseco e poi portarlo in quello standard
|
||||
vCenPtg[nIdOk].first.ToLoc( frIntr) ;
|
||||
vCenPtg[nIdOk].second.ToLoc( frIntr) ;
|
||||
Point3d ptNEloc = ptNearEnd ;
|
||||
ptNEloc.ToLoc( frIntr) ;
|
||||
if ( pCrvArc->SetC2P( vCenPtg[nIdOk].first, vCenPtg[nIdOk].second, ptNEloc) &&
|
||||
pCrvArc->ToGlob( frIntr))
|
||||
return Release( pCrvArc) ;
|
||||
else
|
||||
return nullptr ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Come la CurveArc::Set2PD, ma se raggio infinito restituisce una retta
|
||||
//----------------------------------------------------------------------------
|
||||
ICurve*
|
||||
GetArc2PD( const Point3d& ptStart, const Point3d& ptEnd, double dDirStartDeg)
|
||||
{
|
||||
// creo l'oggetto arco
|
||||
ICurveArc* pArc = CreateCurveArc() ;
|
||||
if ( pArc == nullptr)
|
||||
return nullptr ;
|
||||
// inizializzo il puntatore a curva con l'arco
|
||||
PtrOwner<ICurve> pCrv( pArc) ;
|
||||
|
||||
// calcolo l'arco, se ok lo restituisco ed esco
|
||||
if ( pArc->Set2PD( ptStart, ptEnd, dDirStartDeg))
|
||||
return Release( pCrv) ;
|
||||
|
||||
// calcolo arco non riuscito, verifico se retta va bene
|
||||
Vector3d vtDiff = ptEnd - ptStart ;
|
||||
vtDiff.z = 0 ;
|
||||
Vector3d vtDir = FromPolar( 1, dDirStartDeg) ;
|
||||
// verifico se i punti sono allineati con la direzione e nel giusto verso
|
||||
if ( fabs( CrossXY( vtDiff, vtDir)) < EPS_SMALL && ScalarXY( vtDiff, vtDir) > EPS_SMALL) {
|
||||
// creo l'oggetto retta
|
||||
ICurveLine* pLine = CreateCurveLine() ;
|
||||
if ( pLine == nullptr)
|
||||
return nullptr ;
|
||||
// inizializzo il puntatore a curva con la retta
|
||||
pCrv.Set( pLine) ;
|
||||
// calcolo retta, se ok la restituisco ed esco
|
||||
if ( pLine->Set( ptStart, ptEnd))
|
||||
return Release( pCrv) ;
|
||||
}
|
||||
|
||||
return nullptr ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
ICurve*
|
||||
GetArcPntDirTgArc( const Point3d& ptP, double dDirStartDeg, const ICurveArc& crvArc, const Point3d& ptNearTg)
|
||||
{
|
||||
// se il raggio è praticamente nullo
|
||||
if ( crvArc.GetRadius() < EPS_SMALL) {
|
||||
return GetArc2PD( ptP, crvArc.GetCenter(), dDirStartDeg) ;
|
||||
}
|
||||
|
||||
// versore ortogonale alla direzione iniziale (si lavora nel piano XY locale)
|
||||
Vector3d vtOrtho = FromPolar( 1, dDirStartDeg) ;
|
||||
vtOrtho.Rotate( Z_AX, 0, 1) ;
|
||||
|
||||
// calcolo arco spostando il punto iniziale di + raggio in direzione ortogonale
|
||||
Point3d ptP1 = ptP + vtOrtho * crvArc.GetRadius() ;
|
||||
PtrOwner<ICurve> pCrv1( GetArc2PD( ptP1, crvArc.GetCenter(), dDirStartDeg)) ;
|
||||
bool bOk1 = ( ! IsNull( pCrv1)) ;
|
||||
// compenso lo spostamento ( più -> offset a destra)
|
||||
bOk1 = bOk1 && pCrv1->SimpleOffset( crvArc.GetRadius()) ;
|
||||
// verifico se il punto di tangenza sta sull'arco
|
||||
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)) ;
|
||||
bool bOk2 = ( ! IsNull( pCrv2)) ;
|
||||
// compenso lo spostamento ( meno -> offset a sinistra)
|
||||
bOk2 = bOk2 && pCrv2->SimpleOffset( - crvArc.GetRadius()) ;
|
||||
// verifico se il punto di tangenza sta sull'arco
|
||||
Point3d ptEnd2 ;
|
||||
bOk2 = bOk2 && pCrv2->GetEndPoint( ptEnd2) && crvArc.IsPointOn( ptEnd2) ;
|
||||
|
||||
// se due soluzioni, verifico quale ha il punto di tg più vicino al richiesto
|
||||
if ( bOk1 && bOk2) {
|
||||
if ( SqDist( ptEnd1, ptNearTg) <= SqDist( ptEnd2, ptNearTg))
|
||||
bOk2 = false ;
|
||||
else
|
||||
bOk1 = false ;
|
||||
}
|
||||
|
||||
// restituisco la soluzione
|
||||
if ( bOk1)
|
||||
return Release( pCrv1) ;
|
||||
else if ( bOk2)
|
||||
return Release( pCrv2) ;
|
||||
else
|
||||
return nullptr ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static 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 ;
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
#include "/EgtDev/Include/EGkAngle.h"
|
||||
#include "/EgtDev/Include/EgkCurveLine.h"
|
||||
#include "/EgtDev/Include/EgkCurveComposite.h"
|
||||
#include "/EgtDev/Include/EgkArcXxTgArc.h"
|
||||
#include "/EgtDev/Include/EgkArcSpecial.h"
|
||||
#include "/EgtDev/Include/EGkDistPointCurve.h"
|
||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||
|
||||
|
||||
@@ -0,0 +1,250 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2015-2015
|
||||
//----------------------------------------------------------------------------
|
||||
// File : CircleCenTgCurve.cpp Data : 12.03.15 Versione : 1.6c2
|
||||
// Contenuto : Implementazione funzioni per calcolo circonferenze di centro
|
||||
// dato tangenti a curve.
|
||||
//
|
||||
//
|
||||
// Modifiche : 12.03.15 DS Creazione modulo.
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "CurveBezier.h"
|
||||
#include "CurveComposite.h"
|
||||
#include "CreateCurveAux.h"
|
||||
#include "DistPointLine.h"
|
||||
#include "GeoConst.h"
|
||||
#include "/EgtDev/Include/EgkCircleCenTgCurve.h"
|
||||
#include "/EgtDev/Include/EgkDistPointCurve.h"
|
||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||
|
||||
using namespace std ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static CurveArc* GetCircleCenTgLine( const Point3d& ptCen, const Vector3d& vtN, const CurveLine& crvLine,
|
||||
const Point3d& ptNear, Point3d* pPtTg) ;
|
||||
static CurveArc* GetCircleCenTgArc( const Point3d& ptCen, const Vector3d& vtN, const CurveArc& crvArc,
|
||||
const Point3d& ptNear, Point3d* pPtTg) ;
|
||||
static CurveArc* GetCircleCenTgBezier( const Point3d& ptCen, const Vector3d& vtN, const CurveBezier& crvBezier,
|
||||
const Point3d& ptNear, Point3d* pPtTg) ;
|
||||
static CurveArc* GetCircleCenTgCompo( const Point3d& ptCen, const Vector3d& vtN, const CurveComposite& crvCompo,
|
||||
const Point3d& ptNear, Point3d* pPtTg) ;
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
ICurveArc*
|
||||
GetCircleCenTgCurve( const Point3d& ptCen, const Vector3d& vtN, const ICurve& cCrv, const Point3d& ptNear)
|
||||
{
|
||||
return GetCircleCenTgCurve( ptCen, vtN, cCrv, ptNear, nullptr) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
ICurveArc*
|
||||
GetCircleCenTgCurve( const Point3d& ptCen, const Vector3d& vtN, const ICurve& cCrv, const Point3d& ptNear,
|
||||
Point3d* pPtTg)
|
||||
{
|
||||
// verifica dei parametri
|
||||
if ( &ptCen == nullptr || &vtN == nullptr || &cCrv == nullptr || &ptNear == nullptr)
|
||||
return nullptr ;
|
||||
// eseguo calcoli a seconda della curva tg
|
||||
switch ( cCrv.GetType()) {
|
||||
case CRV_LINE :
|
||||
{ const CurveLine& crvLine = *GetBasicCurveLine( &cCrv) ;
|
||||
return GetCircleCenTgLine( ptCen, vtN, crvLine, ptNear, pPtTg) ; }
|
||||
case CRV_ARC :
|
||||
{ const CurveArc& crvArc = *GetBasicCurveArc( &cCrv) ;
|
||||
return GetCircleCenTgArc( ptCen, vtN, crvArc, ptNear, pPtTg) ; }
|
||||
case CRV_BEZ :
|
||||
{ const CurveBezier& crvBezier = *GetBasicCurveBezier( &cCrv) ;
|
||||
return GetCircleCenTgBezier( ptCen, vtN, crvBezier, ptNear, pPtTg) ; }
|
||||
case CRV_COMPO :
|
||||
{ const CurveComposite& crvCompo = *GetBasicCurveComposite( &cCrv) ;
|
||||
return GetCircleCenTgCompo( ptCen, vtN, crvCompo, ptNear, pPtTg) ; }
|
||||
default :
|
||||
return nullptr ;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
CurveArc*
|
||||
GetCircleCenTgLine( const Point3d& ptCen, const Vector3d& vtN, const CurveLine& crvLine,
|
||||
const Point3d& ptNear, Point3d* pPtTg)
|
||||
{
|
||||
// devo considerare sempre la proiezione della linea sul piano della circonferenza
|
||||
Point3d ptP1 = crvLine.GetStart() ;
|
||||
Point3d ptP2 = crvLine.GetEnd() ;
|
||||
ptP2 -= (( ptP2 - ptP1) * vtN) * vtN ;
|
||||
// calcolo la proiezione perpendicolare del centro sulla linea
|
||||
Point3d ptTg ;
|
||||
if ( ! DistPointLine( ptCen, ptP1, ptP2, false).GetMinDistPoint( ptTg))
|
||||
return nullptr ;
|
||||
// verifico che stia sul segmento
|
||||
double dSqDist ;
|
||||
if ( ! DistPointLine( ptTg, ptP1, ptP2).GetSqDist( dSqDist) || dSqDist > EPS_SMALL * EPS_SMALL)
|
||||
return nullptr ;
|
||||
|
||||
// creo l'arco
|
||||
PtrOwner<CurveArc> pCrvArc( CreateBasicCurveArc()) ;
|
||||
if ( IsNull( pCrvArc))
|
||||
return nullptr ;
|
||||
|
||||
// costruisco la circonferenza corrispondente alla soluzione scelta
|
||||
double dRad = (( ptTg - ptCen) ^ vtN).Len() ;
|
||||
if ( pCrvArc->Set( ptCen, vtN, dRad)) {
|
||||
if ( pPtTg != nullptr)
|
||||
*pPtTg = ptTg ;
|
||||
return Release( pCrvArc) ;
|
||||
}
|
||||
else
|
||||
return nullptr ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
CurveArc*
|
||||
GetCircleCenTgArc( const Point3d& ptCen, const Vector3d& vtN, const CurveArc& crvArc,
|
||||
const Point3d& ptNear, Point3d* pPtTg)
|
||||
{
|
||||
// verifico che la normale della circonferenza coincida con quella dell'arco di tg
|
||||
if ( ! AreSameOrOppositeVectorApprox( vtN, crvArc.GetNormVersor()))
|
||||
return nullptr ;
|
||||
|
||||
// calcolo il riferimento intrinseco dell'arco (DirNorm->Z e DirStart->X)
|
||||
Frame3d frIntr ;
|
||||
if ( ! frIntr.Set( crvArc.GetCenter(), crvArc.GetNormVersor(), crvArc.GetStartVersor()))
|
||||
return nullptr ;
|
||||
|
||||
// porto il punto nel riferimento intrinseco
|
||||
Point3d ptCLoc = ptCen ;
|
||||
ptCLoc.ToLoc( frIntr) ;
|
||||
|
||||
// calcolo le circonferenze tangenti alla circonferenza
|
||||
BIPNTVECTOR vCenPtg( 2) ;
|
||||
int nSol = CalcCircleCenTgCircle( ptCLoc, ORIG, crvArc.GetRadius(), vCenPtg) ;
|
||||
if ( nSol == 0)
|
||||
return nullptr ;
|
||||
|
||||
// porto i punti nel riferimento standard dell'arco
|
||||
for ( size_t i = 0 ; i < vCenPtg.size() ; ++ i) {
|
||||
vCenPtg[i].first.ToGlob( frIntr) ;
|
||||
vCenPtg[i].second.ToGlob( frIntr) ;
|
||||
}
|
||||
|
||||
// se l'arco di tangenza ha deltaN, devo applicarlo in proporzione a questi punti
|
||||
if ( fabs( crvArc.GetDeltaN()) > EPS_SMALL) {
|
||||
for ( size_t i = 0 ; i < vCenPtg.size() ; ++ i) {
|
||||
double dAngDeg ;
|
||||
if ( crvArc.CalcPointAngle( vCenPtg[i].second, dAngDeg))
|
||||
vCenPtg[i].second += crvArc.GetNormVersor() * crvArc.GetDeltaN() * dAngDeg / crvArc.GetAngCenter() ;
|
||||
}
|
||||
}
|
||||
|
||||
// elimino le soluzioni che non stanno sull'arco
|
||||
for ( int i = 1 ; i >= 0 ; -- i) {
|
||||
if ( nSol > i) {
|
||||
if ( ! crvArc.IsPointOn( vCenPtg[i].second)) {
|
||||
-- nSol ;
|
||||
for ( int j = i ; j < nSol ; ++ j)
|
||||
vCenPtg[j] = vCenPtg[j+1] ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// se non sono rimaste soluzioni, esco
|
||||
if ( nSol == 0)
|
||||
return nullptr ;
|
||||
|
||||
// scelgo la soluzione più vicina al punto di riferimento
|
||||
int nIdOk = 0 ;
|
||||
double dMinSqDist = INFINITO * INFINITO ;
|
||||
for ( int i = 0 ; i < nSol ; ++ i) {
|
||||
double dSqDist = SqDist( vCenPtg[i].second, ptNear) ;
|
||||
if ( dSqDist < dMinSqDist) {
|
||||
dMinSqDist = dSqDist ;
|
||||
nIdOk = i ;
|
||||
}
|
||||
}
|
||||
|
||||
// creo l'arco
|
||||
PtrOwner<CurveArc> pCrvArc( CreateBasicCurveArc()) ;
|
||||
if ( IsNull( pCrvArc))
|
||||
return nullptr ;
|
||||
|
||||
// costruisco la circonferenza corrispondente alla soluzione scelta
|
||||
double dRad = (( vCenPtg[nIdOk].second - vCenPtg[nIdOk].first) ^ vtN).Len() ;
|
||||
if ( pCrvArc->Set( vCenPtg[nIdOk].first, vtN, dRad)) {
|
||||
if ( pPtTg != nullptr)
|
||||
*pPtTg = vCenPtg[nIdOk].second ;
|
||||
return Release( pCrvArc) ;
|
||||
}
|
||||
else
|
||||
return nullptr ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
CurveArc*
|
||||
GetCircleCenTgBezier( const Point3d& ptCen, const Vector3d& vtN, const CurveBezier& crvBezier,
|
||||
const Point3d& ptNear, Point3d* pPtTg)
|
||||
{
|
||||
// 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 circonferenza tangente a questa approssimazione
|
||||
Point3d ptTg ;
|
||||
PtrOwner<CurveArc> pCrvArc( GetBasicCurveArc( GetCircleCenTgCurve( ptCen, vtN, *pCrvCompo, ptNear, &ptTg))) ;
|
||||
if ( IsNull( pCrvArc))
|
||||
return nullptr ;
|
||||
// porto il punto di tangenza della circonferenza esattamente sulla curva di Bezier
|
||||
DistPointCurve dstPtCurve( ptTg, crvBezier) ;
|
||||
Point3d ptTg2 ;
|
||||
int nFlag ;
|
||||
if ( ! dstPtCurve.GetMinDistPoint( 0, ptTg2, nFlag))
|
||||
return nullptr ;
|
||||
// calcolo il nuovo raggio
|
||||
double dRad = (( ptTg2 - ptCen) ^ vtN).Len() ;
|
||||
// imposto il nuovo raggio
|
||||
if ( ! pCrvArc->Set( ptCen, vtN, dRad))
|
||||
return nullptr ;
|
||||
// se richiesto, assegno il punto di tg
|
||||
if ( pPtTg != nullptr)
|
||||
*pPtTg = ptTg2 ;
|
||||
// restituisco la circonferenza
|
||||
return Release( pCrvArc) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
CurveArc*
|
||||
GetCircleCenTgCompo( const Point3d& ptCen, const Vector3d& vtN, const CurveComposite& crvCompo,
|
||||
const Point3d& ptNear, Point3d* pPtTg)
|
||||
{
|
||||
// ciclo sulla curva composita
|
||||
double dMinSqDist = INFINITO * INFINITO ;
|
||||
PtrOwner<CurveArc> pCrvArc ;
|
||||
for ( const ICurve* pCrv = crvCompo.GetFirstCurve() ;
|
||||
pCrv != nullptr ;
|
||||
pCrv = crvCompo.GetNextCurve()) {
|
||||
// recupero la circonferenza tangente alla curva elementare
|
||||
Point3d ptTg ;
|
||||
PtrOwner<CurveArc> pCrvAtmp( GetBasicCurveArc( GetCircleCenTgCurve( ptCen, vtN, *pCrv, ptNear, &ptTg))) ;
|
||||
if ( IsNull( pCrvAtmp))
|
||||
continue ;
|
||||
// verifico se è la più vicina al punto desiderato
|
||||
double dSqDist = SqDist( ptNear, ptTg) ;
|
||||
if ( dSqDist < dMinSqDist) {
|
||||
dMinSqDist = dSqDist ;
|
||||
pCrvArc.Set( Release( pCrvAtmp)) ;
|
||||
if ( pPtTg != nullptr)
|
||||
*pPtTg = ptTg ;
|
||||
}
|
||||
}
|
||||
|
||||
return Release( pCrvArc) ;
|
||||
}
|
||||
@@ -74,6 +74,53 @@ CalcLinePointTgCircle( const Point3d& ptP, const Point3d& ptCen, double dRad, BI
|
||||
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)
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int CalcLinePointTgCircle( const Point3d& ptP, const Point3d& ptCen, double dRad, BIPNTVECTOR& vBiPnt) ;
|
||||
int CalcCircleCenTgCircle( const Point3d& ptC, const Point3d& ptCen, double dRad, BIPNTVECTOR& vCenPtg) ;
|
||||
bool FindPointOnArc( const CurveArc& crvArc, const Vector3d& vtDirP, const Point3d& ptNear, Point3d& ptP) ;
|
||||
|
||||
|
||||
|
||||
@@ -1136,6 +1136,43 @@ CurveArc::SimpleOffset( double dDist, int nType)
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CurveArc::ExtendedOffset( double dDist, int nType)
|
||||
{
|
||||
// la curva deve essere validata
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
|
||||
// determinazione versore normale al piano di offset
|
||||
Vector3d vtNref = Z_AX ;
|
||||
if ( ! m_VtExtr.IsSmall())
|
||||
vtNref = m_VtExtr ;
|
||||
|
||||
// la normale deve coincidere con il versore del piano di offset
|
||||
if ( ! AreSameOrOppositeVectorApprox( m_VtN, vtNref))
|
||||
return false ;
|
||||
|
||||
// calcolo il nuovo raggio e lo valido
|
||||
bool bCCW = ( ( m_dAngCenDeg > 0 && m_VtN * vtNref > 0) ||
|
||||
( m_dAngCenDeg < 0 && m_VtN * vtNref < 0)) ;
|
||||
double dNewRad = m_dRad + ( bCCW ? + dDist : - dDist) ;
|
||||
if ( fabs( dNewRad) < EPS_SMALL)
|
||||
return false ;
|
||||
if ( dNewRad < 0) {
|
||||
dNewRad = - dNewRad ;
|
||||
m_VtS = - m_VtS ;
|
||||
}
|
||||
|
||||
// aggiorno il raggio
|
||||
m_dRad = dNewRad ;
|
||||
|
||||
// con i controlli sopra fatti rimane validata, ma la grafica va ricalcolata
|
||||
m_OGrMgr.Reset() ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CurveArc::ModifyStart( const Point3d& ptNewStart)
|
||||
|
||||
@@ -155,6 +155,7 @@ class CurveArc : public ICurveArc, public IGeoObjRW
|
||||
virtual bool InvertN( void) ;
|
||||
virtual bool ChangeRadius( double dNewRadius) ;
|
||||
virtual bool ChangeDeltaN( double dNewDeltaN) ;
|
||||
virtual bool ExtendedOffset( double dDist, int nType = OFF_FILLET) ;
|
||||
virtual bool ToAdditional( void) ;
|
||||
virtual bool Flip( void) ;
|
||||
|
||||
|
||||
Binary file not shown.
@@ -248,11 +248,14 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Angle.cpp" />
|
||||
<ClCompile Include="ArcXxTgArc.cpp" />
|
||||
<ClCompile Include="ArcCenTgCurvePnt.cpp" />
|
||||
<ClCompile Include="ArcPntDirTgCurve.cpp" />
|
||||
<ClCompile Include="ArcSpecial.cpp" />
|
||||
<ClCompile Include="Attribs.cpp" />
|
||||
<ClCompile Include="BBox3d.cpp" />
|
||||
<ClCompile Include="BiArcs.cpp" />
|
||||
<ClCompile Include="ChainCurves.cpp" />
|
||||
<ClCompile Include="CircleCenTgCurve.cpp" />
|
||||
<ClCompile Include="Color.cpp" />
|
||||
<ClCompile Include="CreateCurveAux.cpp" />
|
||||
<ClCompile Include="CurveByInterp.cpp" />
|
||||
@@ -334,10 +337,12 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\Include\EGkAngle.h" />
|
||||
<ClInclude Include="..\Include\EGkArcXxTgArc.h" />
|
||||
<ClInclude Include="..\Include\EGkArcPntDirTgCurve.h" />
|
||||
<ClInclude Include="..\Include\EgkArcSpecial.h" />
|
||||
<ClInclude Include="..\Include\EGkBBox3d.h" />
|
||||
<ClInclude Include="..\Include\EGkBiArcs.h" />
|
||||
<ClInclude Include="..\Include\EGkChainCurves.h" />
|
||||
<ClInclude Include="..\Include\EGkCircleCenTgCurve.h" />
|
||||
<ClInclude Include="..\Include\EGkColor.h" />
|
||||
<ClInclude Include="..\Include\EgkCurve.h" />
|
||||
<ClInclude Include="..\Include\EgkCurveArc.h" />
|
||||
|
||||
@@ -186,9 +186,6 @@
|
||||
<ClCompile Include="LinePntTgCurve.cpp">
|
||||
<Filter>File di origine\GeoCreate</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ArcXxTgArc.cpp">
|
||||
<Filter>File di origine\GeoCreate</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="IntersLineLine.cpp">
|
||||
<Filter>File di origine\GeoInters</Filter>
|
||||
</ClCompile>
|
||||
@@ -264,6 +261,18 @@
|
||||
<ClCompile Include="IntersLineSurfTm.cpp">
|
||||
<Filter>File di origine\GeoInters</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CircleCenTgCurve.cpp">
|
||||
<Filter>File di origine\GeoCreate</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ArcPntDirTgCurve.cpp">
|
||||
<Filter>File di origine\GeoCreate</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ArcCenTgCurvePnt.cpp">
|
||||
<Filter>File di origine\GeoCreate</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ArcSpecial.cpp">
|
||||
<Filter>File di origine\GeoCreate</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="stdafx.h">
|
||||
@@ -425,9 +434,6 @@
|
||||
<ClInclude Include="..\Include\EGkAngle.h">
|
||||
<Filter>File di intestazione\Include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\Include\EGkArcXxTgArc.h">
|
||||
<Filter>File di intestazione\Include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\Include\EGkBBox3d.h">
|
||||
<Filter>File di intestazione\Include</Filter>
|
||||
</ClInclude>
|
||||
@@ -614,6 +620,15 @@
|
||||
<ClInclude Include="ProjPlane.h">
|
||||
<Filter>File di intestazione</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\Include\EGkCircleCenTgCurve.h">
|
||||
<Filter>File di intestazione\Include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\Include\EGkArcPntDirTgCurve.h">
|
||||
<Filter>File di intestazione\Include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\Include\EgkArcSpecial.h">
|
||||
<Filter>File di intestazione\Include</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="EgtGeomKernel.rc">
|
||||
|
||||
+7
-4
@@ -28,7 +28,10 @@
|
||||
#include "/EgtDev/Include/EgkLinePntTgCurve.h"
|
||||
#include "/EgtDev/Include/EgkLineTgTwoCurves.h"
|
||||
#include "/EgtDev/Include/EgkCurveArc.h"
|
||||
#include "/EgtDev/Include/EgkArcXxTgArc.h"
|
||||
#include "/EgtDev/Include/EgkCircleCenTgCurve.h"
|
||||
#include "/EgtDev/Include/EgkArcPntDirTgCurve.h"
|
||||
#include "/EgtDev/Include/EgkArcCenTgCurvePnt.h"
|
||||
#include "/EgtDev/Include/EgkArcSpecial.h"
|
||||
#include "/EgtDev/Include/EgkCurveBezier.h"
|
||||
#include "/EgtDev/Include/EgkCurveComposite.h"
|
||||
#include "/EgtDev/Include/EgkDistPointCurve.h"
|
||||
@@ -1268,7 +1271,7 @@ GdbExecutor::CurveCircleCenterTgArc( const STRVECTOR& vsParams)
|
||||
Point3d ptNloc = ptNear ;
|
||||
ptNloc.LocToLoc( frDest, frTgArc) ;
|
||||
// calcolo la circonferenza tangente all'arco
|
||||
ICurveArc* pNewArc = GetCircleCenTgArc( ptCloc, *pTgArc, ptNloc) ;
|
||||
ICurveArc* pNewArc = GetCircleCenTgCurve( ptCloc, pTgArc->GetNormVersor(), *pTgArc, ptNloc) ;
|
||||
if ( pNewArc == nullptr)
|
||||
return false ;
|
||||
// porto il nuovo arco nel riferimento del gruppo destinazione
|
||||
@@ -1320,7 +1323,7 @@ GdbExecutor::CurveArcCenterTgArcP( const STRVECTOR& vsParams)
|
||||
Point3d ptNeloc = ptNear ;
|
||||
ptNeloc.LocToLoc( frDest, frTgArc) ;
|
||||
// calcolo la circonferenza tangente all'arco
|
||||
ICurveArc* pNewArc = GetArcCenTgArcPnt( ptCloc, *pTgArc, ptNtloc, ptNeloc) ;
|
||||
ICurveArc* pNewArc = GetArcCenTgCurvePnt( ptCloc, *pTgArc, ptNtloc, ptNeloc, Z_AX) ;
|
||||
if ( pNewArc == nullptr)
|
||||
return false ;
|
||||
// porto il nuovo arco nel riferimento del gruppo destinazione
|
||||
@@ -1370,7 +1373,7 @@ GdbExecutor::CurveArcPDiTgArc( const STRVECTOR& vsParams)
|
||||
Point3d ptNtloc = ptNear ;
|
||||
ptNtloc.LocToLoc( frDest, frTgArc) ;
|
||||
// calcolo l'arco (in casi particolari può essere una linea)
|
||||
ICurve* pCurve = GetArcPntDirTgArc( ptSloc, dDirI, *pTgArc, ptNtloc) ;
|
||||
ICurve* pCurve = GetArcPntDirTgCurve( ptSloc, FromPolar( 1, dDirI), *pTgArc, ptNtloc, Z_AX) ;
|
||||
if ( pCurve == nullptr)
|
||||
return false ;
|
||||
// porto il nuovo arco nel riferimento del gruppo destinazione
|
||||
|
||||
@@ -105,6 +105,15 @@ GetLinePointTgArc( const Point3d& ptP, const CurveArc& crvArc, const Point3d& pt
|
||||
vBiPnt[i].second.ToGlob( frIntr) ;
|
||||
}
|
||||
|
||||
// se l'arco di tangenza ha deltaN, devo applicarlo in proporzione a questi punti
|
||||
if ( fabs( crvArc.GetDeltaN()) > EPS_SMALL) {
|
||||
for ( size_t i = 0 ; i < vBiPnt.size() ; ++ i) {
|
||||
double dAngDeg ;
|
||||
if ( crvArc.CalcPointAngle( vBiPnt[i].second, dAngDeg))
|
||||
vBiPnt[i].second += crvArc.GetNormVersor() * crvArc.GetDeltaN() * dAngDeg / crvArc.GetAngCenter() ;
|
||||
}
|
||||
}
|
||||
|
||||
// elimino le soluzioni che non stanno sull'arco
|
||||
for ( int i = 1 ; i >= 0 ; -- i) {
|
||||
if ( nSol > i) {
|
||||
|
||||
+15
-13
@@ -232,10 +232,11 @@ SurfTriMesh::GetFacetNearestEndPoint( int nF, const Point3d& ptNear, Point3d& pt
|
||||
dMinSqDist = dSqDist ;
|
||||
ptEnd = ptTest ;
|
||||
bFound = true ;
|
||||
// recupero la normale
|
||||
Vector3d vtN1, vtN2 ;
|
||||
if ( ! GetTriangleSmoothNormal( nT, j, vtN))
|
||||
vtN = m_vTria[nT].vtN ;
|
||||
// recupero la normale della faccia (non quella mediata del vertice)
|
||||
vtN = m_vTria[nT].vtN ;
|
||||
//Vector3d vtN1, vtN2 ;
|
||||
//if ( ! GetTriangleSmoothNormal( nT, j, vtN))
|
||||
// vtN = m_vTria[nT].vtN ;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -269,15 +270,16 @@ SurfTriMesh::GetFacetNearestMidPoint( int nF, const Point3d& ptNear, Point3d& pt
|
||||
dMinSqDist = dSqDist ;
|
||||
ptMid = ptTest ;
|
||||
bFound = true ;
|
||||
// calcolo la normale
|
||||
Vector3d vtN1, vtN2 ;
|
||||
if ( GetTriangleSmoothNormal( nT, j, vtN1) &&
|
||||
GetTriangleSmoothNormal( nT, k, vtN2)) {
|
||||
vtN = Media( vtN1, vtN2, 0.5) ;
|
||||
vtN.Normalize() ;
|
||||
}
|
||||
else
|
||||
vtN = m_vTria[nT].vtN ;
|
||||
// recupero la normale della faccia (non quella mediata del vertice)
|
||||
vtN = m_vTria[nT].vtN ;
|
||||
//Vector3d vtN1, vtN2 ;
|
||||
//if ( GetTriangleSmoothNormal( nT, j, vtN1) &&
|
||||
// GetTriangleSmoothNormal( nT, k, vtN2)) {
|
||||
// vtN = Media( vtN1, vtN2, 0.5) ;
|
||||
// vtN.Normalize() ;
|
||||
//}
|
||||
//else
|
||||
// vtN = m_vTria[nT].vtN ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user