139ac4c11c
- a CurveArc aggiunti metodi SetCPA e SetCPAN - a SurfFlatRegion aggiunto metodo GetChunkCentroid e corretto GetCentroid - a SurfFlatRegion aggiunti metodi TranslateSimpleNoCollision e RotateSimpleNoCollision.
456 lines
17 KiB
C++
456 lines
17 KiB
C++
//----------------------------------------------------------------------------
|
|
// EgalTech 2015-2015
|
|
//----------------------------------------------------------------------------
|
|
// File : SurfFlatRegionNoCollisionMove.cpp Data : 29.12.15 Versione : 1.6l5
|
|
// Contenuto : Implementazione delle funzioni di movimento per SurfFlatRegion
|
|
// senza collisione con altri oggetti dello stesso tipo e nello
|
|
// stesso piano o in piani paralleli.
|
|
//
|
|
//
|
|
// Modifiche : 29.12.15 DS Creazione modulo.
|
|
//
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
//--------------------------- Include ----------------------------------------
|
|
#include "stdafx.h"
|
|
#include "SurfFlatRegion.h"
|
|
#include "CurveLine.h"
|
|
#include "CurveArc.h"
|
|
#include "CurveComposite.h"
|
|
#include "IntersLineArc.h"
|
|
#include "GeoConst.h"
|
|
#include "/EgtDev/Include/EgtPointerOwner.h"
|
|
|
|
using namespace std ;
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
TranslateLineNoCollisionLine( const CurveLine* pLine1, const CurveLine* pLine2,
|
|
const Vector3d& vtDir, double& dLen)
|
|
{
|
|
// versore ortogonale al movimento
|
|
Vector3d vtNorm( vtDir.y, - vtDir.x, 0) ;
|
|
// coordinate degli estremi dei segmenti nel riferimento formato da O=L1Start X=vtNorm Y=vtDir
|
|
Point3d ptS1( 0, 0, 0) ;
|
|
Point3d ptE1( ( pLine1->GetEnd() - pLine1->GetStart()) * vtNorm,
|
|
( pLine1->GetEnd() - pLine1->GetStart()) * vtDir, 0) ;
|
|
Point3d ptS2( ( pLine2->GetStart() - pLine1->GetStart()) * vtNorm,
|
|
( pLine2->GetStart() - pLine1->GetStart()) * vtDir, 0) ;
|
|
Point3d ptE2( ( pLine2->GetEnd() - pLine1->GetStart()) * vtNorm,
|
|
( pLine2->GetEnd() - pLine1->GetStart()) * vtDir, 0) ;
|
|
// perpendicolari esterne alle due linee (nel riferimento sopra definito)
|
|
Vector3d vtN1( ( ptE1.y - ptS1.y), - ( ptE1.x - ptS1.x), 0) ;
|
|
Vector3d vtN2( ( ptE2.y - ptS2.y), - ( ptE2.x - ptS2.x), 0) ;
|
|
// eseguo culling (le linee sono il contorno di una area chiusa)
|
|
if ( vtN1.y <= 0 || vtN2.y >= 0)
|
|
return true ;
|
|
// ordino l'intervallo della prima linea secondo X crescenti
|
|
if ( ptS1.x > ptE1.x)
|
|
swap( ptS1, ptE1) ;
|
|
// ordino l'intervallo della seconda linea secondo X crescenti
|
|
if ( ptS2.x > ptE2.x)
|
|
swap( ptS2, ptE2) ;
|
|
// se gli intervalli non si sovrappongono, non ci sono limiti
|
|
if ( ptS1.x > ptE2.x - EPS_SMALL || ptS2.x > ptE1.x - EPS_SMALL)
|
|
return true ;
|
|
// calcolo il minimo movimento degli estremi interni all'intervallo comune
|
|
double dNewLen ;
|
|
if ( ptS1.x >= ptS2.x) {
|
|
double dY2 ;
|
|
if ( abs( ptE2.x - ptS2.x) < EPS_SMALL)
|
|
dY2 = min( ptE2.y, ptS2.y) ;
|
|
else
|
|
dY2 = ptS2.y + ( ptE2.y - ptS2.y) / ( ptE2.x - ptS2.x) * ( ptS1.x - ptS2.x) ;
|
|
dNewLen = dY2 - ptS1.y ;
|
|
}
|
|
else {
|
|
double dY1 ;
|
|
if ( abs( ptE1.x - ptS1.x) < EPS_SMALL)
|
|
dY1 = max( ptE1.y, ptS1.y) ;
|
|
else
|
|
dY1 = ptS1.y + ( ptE1.y - ptS1.y) / ( ptE1.x - ptS1.x) * ( ptS2.x - ptS1.x) ;
|
|
dNewLen = ptS2.y - dY1 ;
|
|
}
|
|
if ( ptE1.x <= ptE2.x) {
|
|
double dY2 ;
|
|
if ( abs( ptE2.x - ptS2.x) < EPS_SMALL)
|
|
dY2 = min( ptE2.y, ptS2.y) ;
|
|
else
|
|
dY2 = ptS2.y + ( ptE2.y - ptS2.y) / ( ptE2.x - ptS2.x) * ( ptE1.x - ptS2.x) ;
|
|
dNewLen = min( dNewLen, ( dY2 - ptE1.y)) ;
|
|
}
|
|
else {
|
|
double dY1 ;
|
|
if ( abs( ptE1.x - ptS1.x) < EPS_SMALL)
|
|
dY1 = max( ptE1.y, ptS1.y) ;
|
|
else
|
|
dY1 = ptS1.y + ( ptE1.y - ptS1.y) / ( ptE1.x - ptS1.x) * ( ptE2.x - ptS1.x) ;
|
|
dNewLen = min( dNewLen, ptE2.y - dY1) ;
|
|
}
|
|
// confronto con movimento corrente
|
|
if ( abs( dNewLen) < EPS_SMALL)
|
|
dLen = 0 ;
|
|
else if ( dNewLen > 0)
|
|
dLen = min( dLen, dNewLen) ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
SurfFlatRegion::TranslateSimpleNoCollision( const ISurfFlatRegion& Other, const Vector3d& vtDir,
|
|
double& dLen) const
|
|
{
|
|
// verifico lo stato
|
|
if ( m_nStatus != OK || m_vpLoop.empty())
|
|
return false ;
|
|
// recupero rappresentazione base dell'altra regione
|
|
const SurfFlatRegion& Reg2 = *GetBasicSurfFlatRegion( &Other) ;
|
|
// verifico lo stato dell'altra regione
|
|
if ( &Reg2 == nullptr || Reg2.m_nStatus != OK || Reg2.m_vpLoop.empty())
|
|
return false ;
|
|
|
|
// verifico che le due regioni giacciano in piani paralleli
|
|
if ( ! AreSameVectorApprox( m_frF.VersZ(), Reg2.m_frF.VersZ()))
|
|
return false ;
|
|
|
|
// porto il vettore di movimento nel riferimento intrinseco e ne annullo la componente Z
|
|
Vector3d vtDirL = vtDir ;
|
|
vtDirL.ToLoc( m_frF) ;
|
|
vtDirL.z = 0 ;
|
|
double dLenXY = vtDirL.Len() ;
|
|
if ( dLenXY < EPS_SMALL)
|
|
return true ;
|
|
vtDirL /= dLenXY ;
|
|
dLenXY *= dLen ;
|
|
double dNewLenXY = dLenXY ;
|
|
|
|
// ciclo sui chunk della seconda superficie
|
|
for ( int i = 0 ; i < Reg2.GetChunkCount() ; ++ i) {
|
|
|
|
// curva esterna del chunk della seconda regione in locale nel riferimento intrinseco della prima
|
|
const ICurve* pCrv2Loc = nullptr ;
|
|
PtrOwner<ICurve> pCopyCrv ;
|
|
if ( AreSameFrame( m_frF, Reg2.m_frF))
|
|
pCrv2Loc = Reg2.GetMyLoop( i, 0) ;
|
|
else {
|
|
pCopyCrv.Set( Reg2.GetMyLoop( i, 0)->Clone()) ;
|
|
if ( IsNull( pCopyCrv))
|
|
return REGC_NULL ;
|
|
pCopyCrv->LocToLoc( Reg2.m_frF, m_frF) ;
|
|
pCrv2Loc = Get( pCopyCrv) ;
|
|
}
|
|
|
|
// ciclo sui chunk della prima superficie
|
|
for ( int j = 0 ; j < GetChunkCount() ; ++ j) {
|
|
|
|
// curva esterna del chunk della prima regione (ovviamente già in locale al riferimento intrinseco)
|
|
const ICurve* pCrv1Loc = GetMyLoop( j, 0) ;
|
|
|
|
// verifico la collisione tra le entità dei loop esterni dei due chunk
|
|
// per ora solo curve composite formate esclusivamente da rette
|
|
const CurveComposite* pCompo1 = GetBasicCurveComposite( pCrv1Loc) ;
|
|
const CurveComposite* pCompo2 = GetBasicCurveComposite( pCrv2Loc) ;
|
|
const ICurve* pCrv1 = pCompo1->GetFirstCurve() ;
|
|
while ( pCrv1 != nullptr) {
|
|
const CurveLine* pLine1 = GetBasicCurveLine( pCrv1) ;
|
|
const ICurve* pCrv2 = pCompo2->GetFirstCurve() ;
|
|
while ( pCrv2 != nullptr) {
|
|
const CurveLine* pLine2 = GetBasicCurveLine( pCrv2) ;
|
|
if ( pLine1 == nullptr || pLine2 == nullptr ||
|
|
! TranslateLineNoCollisionLine( pLine1, pLine2, vtDirL, dNewLenXY))
|
|
return false ;
|
|
pCrv2 = pCompo2->GetNextCurve() ;
|
|
}
|
|
pCrv1 = pCompo1->GetNextCurve() ;
|
|
}
|
|
}
|
|
}
|
|
|
|
// se da limitare il movimento
|
|
if ( dNewLenXY < dLenXY - EPS_SMALL)
|
|
dLen *= dNewLenXY / dLenXY ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
RotateLineNoCollisionLine( const CurveLine* pLine1, const CurveLine* pLine2,
|
|
const Point3d& ptCen, double& dAng)
|
|
{
|
|
// senso di rotazione
|
|
bool bCCW = ( dAng > 0) ;
|
|
|
|
// analisi della prima linea
|
|
Point3d ptS1 = pLine1->GetStart() ;
|
|
Point3d ptE1 = pLine1->GetEnd() ;
|
|
Vector3d vtDir1 = ptE1 - ptS1 ;
|
|
vtDir1.z = 0 ;
|
|
double dLen1 = vtDir1.LenXY() ;
|
|
if ( dLen1 < EPS_SMALL)
|
|
return false ;
|
|
vtDir1 /= dLen1 ;
|
|
Vector3d vtN1( vtDir1.y, - vtDir1.x, 0) ;
|
|
// linea per successivi controlli
|
|
CurveLine NewLine1 ;
|
|
// se punto a minima distanza da C non interno al segmento, eseguo direttamente culling su intera linea
|
|
double dUMin1 = ( ptCen - ptS1) * vtDir1 ;
|
|
if ( dUMin1 < EPS_SMALL || dUMin1 > dLen1 - EPS_SMALL) {
|
|
Vector3d vtRad = 0.5 * ( ptE1 + ptS1) - ptCen ;
|
|
Vector3d vtMove = ( bCCW ? Vector3d( - vtRad.y, vtRad.x, 0) : Vector3d( vtRad.y, - vtRad.x, 0)) ;
|
|
if ( vtN1 * vtMove <= 0)
|
|
return true ;
|
|
}
|
|
// altrimenti tengo parte con culling superato
|
|
else {
|
|
// verifico primo estremo
|
|
Vector3d vtRad = ptS1 - ptCen ;
|
|
Vector3d vtMove = ( bCCW ? Vector3d( - vtRad.y, vtRad.x, 0) : Vector3d( vtRad.y, - vtRad.x, 0)) ;
|
|
// se va bene il primo estremo
|
|
if ( vtN1 * vtMove > 0) {
|
|
ptE1 = ptS1 + vtDir1 * dUMin1 ;
|
|
dLen1 = dUMin1 ;
|
|
}
|
|
// altrimenti deve andare bene il secondo
|
|
else {
|
|
ptS1 += vtDir1 * dUMin1 ;
|
|
dLen1 -= dUMin1 ;
|
|
}
|
|
NewLine1.Set( ptE1, ptS1) ;
|
|
pLine1 = &NewLine1 ;
|
|
}
|
|
|
|
// analisi della seconda linea
|
|
Point3d ptS2 = pLine2->GetStart() ;
|
|
Point3d ptE2 = pLine2->GetEnd() ;
|
|
Vector3d vtDir2 = ptE2 - ptS2 ;
|
|
vtDir2.z = 0 ;
|
|
double dLen2 = vtDir2.LenXY() ;
|
|
if ( dLen2 < EPS_SMALL)
|
|
return false ;
|
|
vtDir2 /= dLen2 ;
|
|
Vector3d vtN2( vtDir2.y, - vtDir2.x, 0) ;
|
|
// linea per successivi controlli
|
|
CurveLine NewLine2 ;
|
|
// se punto a minima distanza da C non interno al segmento, eseguo direttamente culling su intera linea
|
|
double dUMin2 = ( ptCen - ptS2) * vtDir2 ;
|
|
if ( dUMin2 < EPS_SMALL || dUMin2 > dLen2 - EPS_SMALL) {
|
|
Vector3d vtRad = 0.5 * ( ptE2 + ptS2) - ptCen ;
|
|
Vector3d vtMove = ( bCCW ? Vector3d( - vtRad.y, vtRad.x, 0) : Vector3d( vtRad.y, - vtRad.x, 0)) ;
|
|
if ( vtN2 * vtMove >= 0)
|
|
return true ;
|
|
}
|
|
// altrimenti tengo parte con culling superato
|
|
else {
|
|
// verifico primo estremo
|
|
Vector3d vtRad = ptS2 - ptCen ;
|
|
Vector3d vtMove = ( bCCW ? Vector3d( - vtRad.y, vtRad.x, 0) : Vector3d( vtRad.y, - vtRad.x, 0)) ;
|
|
// se va bene il primo estremo
|
|
if ( vtN2 * vtMove < 0) {
|
|
ptE2 = ptS2 + vtDir2 * dUMin2 ;
|
|
dLen2 = dUMin2 ;
|
|
}
|
|
// altrimenti deve andare bene il secondo
|
|
else {
|
|
ptS2 += vtDir2 * dUMin2 ;
|
|
dLen2 -= dUMin2 ;
|
|
}
|
|
NewLine2.Set( ptE2, ptS2) ;
|
|
pLine2 = &NewLine2 ;
|
|
}
|
|
|
|
// verifico se gli intervalli radiali si sovrappongono
|
|
Vector3d vtDirS1 = ptS1 - ptCen ;
|
|
double dRadS1 = vtDirS1.LenXY() ;
|
|
Vector3d vtDirE1 = ptE1 - ptCen ;
|
|
double dRadE1 = vtDirE1.LenXY() ;
|
|
Vector3d vtDirS2 = ptS2 - ptCen ;
|
|
double dRadS2 = vtDirS2.LenXY() ;
|
|
Vector3d vtDirE2 = ptE2 - ptCen ;
|
|
double dRadE2 = vtDirE2.LenXY() ;
|
|
|
|
// ordino l'intervallo della prima linea secondo raggi crescenti
|
|
if ( dRadS1 > dRadE1) {
|
|
swap( ptS1, ptE1) ;
|
|
swap( vtDirS1, vtDirE1) ;
|
|
swap( dRadS1, dRadE1) ;
|
|
}
|
|
// ordino l'intervallo della seconda linea secondo raggi crescenti
|
|
if ( dRadS2 > dRadE2) {
|
|
swap( ptS2, ptE2) ;
|
|
swap( vtDirS2, vtDirE2) ;
|
|
swap( dRadS2, dRadE2) ;
|
|
}
|
|
// se gli intervalli non si sovrappongono, non ci sono limiti
|
|
if ( dRadS1 > dRadE2 - EPS_SMALL || dRadS2 > dRadE1 - EPS_SMALL)
|
|
return true ;
|
|
|
|
// calcolo la minima rotazione degli estremi interni all'intervallo comune
|
|
double dNewAng = dAng ;
|
|
if ( dRadS1 >= dRadS2) {
|
|
vtDirS1 /= dRadS1 ;
|
|
CurveArc ArcS1 ;
|
|
ArcS1.Set( ptCen, Z_AX, dRadS1, vtDirS1, dAng, 0) ;
|
|
IntersLineArc intLA( *pLine2, ArcS1) ;
|
|
if ( intLA.GetNumInters() == 2) {
|
|
IntCrvCrvInfo iccInfo1, iccInfo2 ;
|
|
intLA.GetIntCrvCrvInfo( 0, iccInfo1) ;
|
|
intLA.GetIntCrvCrvInfo( 1, iccInfo2) ;
|
|
dNewAng = dAng * min( iccInfo1.IciB[0].dU, iccInfo2.IciB[0].dU) ;
|
|
}
|
|
else if ( intLA.GetNumInters() == 1) {
|
|
IntCrvCrvInfo iccInfo ;
|
|
intLA.GetIntCrvCrvInfo( 0, iccInfo) ;
|
|
dNewAng = dAng * iccInfo.IciB[0].dU ;
|
|
}
|
|
}
|
|
else {
|
|
vtDirS2 /= dRadS2 ;
|
|
CurveArc ArcS2 ;
|
|
ArcS2.Set( ptCen, Z_AX, dRadS2, vtDirS2, - dAng, 0) ;
|
|
IntersLineArc intLA( *pLine1, ArcS2) ;
|
|
if ( intLA.GetNumInters() == 2) {
|
|
IntCrvCrvInfo iccInfo1, iccInfo2 ;
|
|
intLA.GetIntCrvCrvInfo( 0, iccInfo1) ;
|
|
intLA.GetIntCrvCrvInfo( 1, iccInfo2) ;
|
|
dNewAng = dAng * min( iccInfo1.IciB[0].dU, iccInfo2.IciB[0].dU) ;
|
|
}
|
|
else if ( intLA.GetNumInters() == 1) {
|
|
IntCrvCrvInfo iccInfo ;
|
|
intLA.GetIntCrvCrvInfo( 0, iccInfo) ;
|
|
dNewAng = dAng * iccInfo.IciB[0].dU ;
|
|
}
|
|
}
|
|
if ( dRadE1 <= dRadE2) {
|
|
vtDirE1 /= dRadE1 ;
|
|
CurveArc ArcE1 ;
|
|
ArcE1.Set( ptCen, Z_AX, dRadE1, vtDirE1, dAng, 0) ;
|
|
IntersLineArc intLA( *pLine2, ArcE1) ;
|
|
if ( intLA.GetNumInters() == 2) {
|
|
IntCrvCrvInfo iccInfo1, iccInfo2 ;
|
|
intLA.GetIntCrvCrvInfo( 0, iccInfo1) ;
|
|
intLA.GetIntCrvCrvInfo( 1, iccInfo2) ;
|
|
if ( bCCW)
|
|
dNewAng = min( dNewAng, dAng * min( iccInfo1.IciB[0].dU, iccInfo2.IciB[0].dU)) ;
|
|
else
|
|
dNewAng = max( dNewAng, dAng * min( iccInfo1.IciB[0].dU, iccInfo2.IciB[0].dU)) ;
|
|
}
|
|
else if ( intLA.GetNumInters() == 1) {
|
|
IntCrvCrvInfo iccInfo ;
|
|
intLA.GetIntCrvCrvInfo( 0, iccInfo) ;
|
|
if ( bCCW)
|
|
dNewAng = min( dNewAng, dAng * iccInfo.IciB[0].dU) ;
|
|
else
|
|
dNewAng = max( dNewAng, dAng * iccInfo.IciB[0].dU) ;
|
|
}
|
|
}
|
|
else {
|
|
vtDirE2 /= dRadE2 ;
|
|
CurveArc ArcE2 ;
|
|
ArcE2.Set( ptCen, Z_AX, dRadE2, vtDirE2, - dAng, 0) ;
|
|
IntersLineArc intLA( *pLine1, ArcE2) ;
|
|
if ( intLA.GetNumInters() == 2) {
|
|
IntCrvCrvInfo iccInfo1, iccInfo2 ;
|
|
intLA.GetIntCrvCrvInfo( 0, iccInfo1) ;
|
|
intLA.GetIntCrvCrvInfo( 1, iccInfo2) ;
|
|
if ( bCCW)
|
|
dNewAng = min( dNewAng, dAng * min( iccInfo1.IciB[0].dU, iccInfo2.IciB[0].dU)) ;
|
|
else
|
|
dNewAng = max( dNewAng, dAng * min( iccInfo1.IciB[0].dU, iccInfo2.IciB[0].dU)) ;
|
|
}
|
|
else if ( intLA.GetNumInters() == 1) {
|
|
IntCrvCrvInfo iccInfo ;
|
|
intLA.GetIntCrvCrvInfo( 0, iccInfo) ;
|
|
if ( bCCW)
|
|
dNewAng = min( dNewAng, dAng * iccInfo.IciB[0].dU) ;
|
|
else
|
|
dNewAng = max( dNewAng, dAng * iccInfo.IciB[0].dU) ;
|
|
}
|
|
}
|
|
// confronto con rotazione corrente
|
|
if ( abs( dNewAng) < EPS_SMALL)
|
|
dAng = 0 ;
|
|
else if ( bCCW && dNewAng > 0)
|
|
dAng = min( dAng, dNewAng) ;
|
|
else if ( ! bCCW && dNewAng < 0)
|
|
dAng = max( dAng, dNewAng) ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
SurfFlatRegion::RotateSimpleNoCollision( const ISurfFlatRegion& Other, const Point3d& ptCen,
|
|
double& dAng) const
|
|
{
|
|
// verifico lo stato
|
|
if ( m_nStatus != OK || m_vpLoop.empty())
|
|
return false ;
|
|
// recupero rappresentazione base dell'altra regione
|
|
const SurfFlatRegion& Reg2 = *GetBasicSurfFlatRegion( &Other) ;
|
|
// verifico lo stato dell'altra regione
|
|
if ( &Reg2 == nullptr || Reg2.m_nStatus != OK || Reg2.m_vpLoop.empty())
|
|
return false ;
|
|
|
|
// verifico che le due regioni giacciano in piani paralleli
|
|
if ( ! AreSameVectorApprox( m_frF.VersZ(), Reg2.m_frF.VersZ()))
|
|
return false ;
|
|
|
|
// porto il centro di rotazioneo nel riferimento intrinseco e ne annullo la componente Z
|
|
Point3d ptCenL = ptCen ;
|
|
ptCenL.ToLoc( m_frF) ;
|
|
ptCenL.z = 0 ;
|
|
if ( abs( dAng) < EPS_ANG_SMALL)
|
|
return true ;
|
|
double dNewAng = dAng ;
|
|
|
|
// ciclo sui chunk della seconda superficie
|
|
for ( int i = 0 ; i < Reg2.GetChunkCount() ; ++ i) {
|
|
|
|
// curva esterna del chunk della seconda regione in locale nel riferimento intrinseco della prima
|
|
const ICurve* pCrv2Loc = nullptr ;
|
|
PtrOwner<ICurve> pCopyCrv ;
|
|
if ( AreSameFrame( m_frF, Reg2.m_frF))
|
|
pCrv2Loc = Reg2.GetMyLoop( i, 0) ;
|
|
else {
|
|
pCopyCrv.Set( Reg2.GetMyLoop( i, 0)->Clone()) ;
|
|
if ( IsNull( pCopyCrv))
|
|
return REGC_NULL ;
|
|
pCopyCrv->LocToLoc( Reg2.m_frF, m_frF) ;
|
|
pCrv2Loc = Get( pCopyCrv) ;
|
|
}
|
|
|
|
// ciclo sui chunk della prima superficie
|
|
for ( int j = 0 ; j < GetChunkCount() ; ++ j) {
|
|
|
|
// curva esterna del chunk della prima regione (ovviamente già in locale al riferimento intrinseco)
|
|
const ICurve* pCrv1Loc = GetMyLoop( j, 0) ;
|
|
|
|
// verifico la collisione tra le entità dei loop esterni dei due chunk
|
|
// per ora solo curve composite formate esclusivamente da rette
|
|
const CurveComposite* pCompo1 = GetBasicCurveComposite( pCrv1Loc) ;
|
|
const CurveComposite* pCompo2 = GetBasicCurveComposite( pCrv2Loc) ;
|
|
const ICurve* pCrv1 = pCompo1->GetFirstCurve() ;
|
|
while ( pCrv1 != nullptr) {
|
|
const CurveLine* pLine1 = GetBasicCurveLine( pCrv1) ;
|
|
const ICurve* pCrv2 = pCompo2->GetFirstCurve() ;
|
|
while ( pCrv2 != nullptr) {
|
|
const CurveLine* pLine2 = GetBasicCurveLine( pCrv2) ;
|
|
if ( pLine1 == nullptr || pLine2 == nullptr ||
|
|
! RotateLineNoCollisionLine( pLine1, pLine2, ptCenL, dNewAng))
|
|
return false ;
|
|
pCrv2 = pCompo2->GetNextCurve() ;
|
|
}
|
|
pCrv1 = pCompo1->GetNextCurve() ;
|
|
}
|
|
}
|
|
}
|
|
|
|
// se da limitare il movimento
|
|
if ( ( dAng > 0 && dNewAng < dAng - EPS_ANG_SMALL) ||
|
|
( dAng < 0 && dNewAng > dAng + EPS_ANG_SMALL))
|
|
dAng = dNewAng ;
|
|
|
|
return true ;
|
|
}
|