64c954ad4b
- fabs sostituito da abs - in Zmap razionalizzazione operazioni taglio spilloni - in SurfTriMesh UpdateFaceting senza più chiamate recursive.
225 lines
6.3 KiB
C++
225 lines
6.3 KiB
C++
//----------------------------------------------------------------------------
|
|
// EgalTech 2013-2014
|
|
//----------------------------------------------------------------------------
|
|
// File : PolynomialPoint3d.cpp Data : 12.01.14 Versione : 1.5a2
|
|
// Contenuto : Implementazione classe polinomio con coefficienti Point3d.
|
|
//
|
|
//
|
|
//
|
|
// Modifiche : 12.01.14 DS Creazione modulo.
|
|
//
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
//--------------------------- Include ----------------------------------------
|
|
#include "stdafx.h"
|
|
#include "PolynomialPoint3d.h"
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
PolynomialPoint3d::SetDegree( int nDegree)
|
|
{
|
|
// gradi negativi non hanno senso
|
|
if ( nDegree < 0)
|
|
return false ;
|
|
// pulisco, alloco e inizializzo a 0
|
|
try {
|
|
m_Coeff.clear() ;
|
|
m_Coeff.reserve( nDegree + 1) ;
|
|
m_nDegree = nDegree ;
|
|
for ( int i = 0 ; i <= m_nDegree ; ++ i)
|
|
m_Coeff.emplace_back( 0, 0, 0) ;
|
|
return true ;
|
|
}
|
|
catch (...) {
|
|
return false ;
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
PolynomialPoint3d::EnsureDegree( int nDegree)
|
|
{
|
|
// se il grado è già adeguato non devo fare alcunché
|
|
if ( nDegree <= m_nDegree)
|
|
return true ;
|
|
// alloco e inizializzo a 0 i nuovi coefficienti
|
|
try {
|
|
m_Coeff.reserve( nDegree + 1) ;
|
|
for ( int i = m_nDegree + 1 ; i <= nDegree ; ++ i)
|
|
m_Coeff.emplace_back() ;
|
|
m_nDegree = nDegree ;
|
|
return true ;
|
|
}
|
|
catch (...) {
|
|
return false ;
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
PolynomialPoint3d::SetCoeff( int nPower, Point3d& ptP)
|
|
{
|
|
if ( nPower < 0 || nPower > m_nDegree)
|
|
return false ;
|
|
|
|
m_Coeff[nPower] = ptP ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
PolynomialPoint3d::Set( int nDegree, const PNTVECTOR& vP)
|
|
{
|
|
if ( ! SetDegree( nDegree))
|
|
return false ;
|
|
|
|
for ( int i = 0 ; i <= nDegree ; i ++)
|
|
m_Coeff[i] = vP[i] ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
PolynomialPoint3d::SetToConstant( const Point3d& ptP)
|
|
{
|
|
if ( ! SetDegree( 0))
|
|
return false ;
|
|
m_Coeff[0] = ptP ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
PolynomialPoint3d&
|
|
PolynomialPoint3d::operator +=( const PolynomialPoint3d& pol3P)
|
|
{
|
|
// mi assicuro che il polinomio risultante abbia grado sufficiente
|
|
EnsureDegree( pol3P.GetDegree()) ;
|
|
|
|
// eseguo la somma
|
|
for ( int i = 0 ; i <= pol3P.GetDegree() ; ++ i)
|
|
m_Coeff[i] += pol3P.m_Coeff[i] ;
|
|
|
|
return *this ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
PolynomialPoint3d&
|
|
PolynomialPoint3d::operator -=( const PolynomialPoint3d& pol3P)
|
|
{
|
|
// mi assicuro che il polinomio risultante abbia grado sufficiente
|
|
EnsureDegree( pol3P.GetDegree()) ;
|
|
|
|
// eseguo la somma
|
|
for ( int i = 0 ; i <= pol3P.GetDegree() ; ++ i)
|
|
m_Coeff[i] += ( - pol3P.m_Coeff[i]) ;
|
|
|
|
return *this ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
PolynomialPoint3d&
|
|
PolynomialPoint3d::operator *=( const Polynomial& polP)
|
|
{
|
|
// copio il polinomio corrente
|
|
PolynomialPoint3d pol3C = *this ;
|
|
|
|
// pulisco e imposto il grado del polinomio risultante
|
|
SetDegree( pol3C.GetDegree() + polP.GetDegree()) ;
|
|
|
|
// eseguo il prodotto
|
|
for ( int i = 0 ; i <= pol3C.GetDegree() ; ++ i) {
|
|
for ( int j = 0 ; j <= polP.GetDegree() ; ++ j)
|
|
m_Coeff[i+j] += pol3C.m_Coeff[i] * polP.GetCoeff(j) ;
|
|
}
|
|
|
|
return *this ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void
|
|
PolynomialPoint3d::Derive( void)
|
|
{
|
|
// polinomio non inizializzato
|
|
if ( m_nDegree < 0)
|
|
return ;
|
|
// polinomio costante
|
|
if ( m_nDegree == 0) {
|
|
m_Coeff[0] = Point3d( 0, 0, 0) ;
|
|
return ;
|
|
}
|
|
// caso normale
|
|
for ( int i = 0 ; i < m_nDegree ; ++ i)
|
|
m_Coeff[i] = ( i + 1) * m_Coeff[i+1] ;
|
|
m_Coeff.pop_back() ;
|
|
-- m_nDegree ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void
|
|
PolynomialPoint3d::Derive( const PolynomialPoint3d& pol3P)
|
|
{
|
|
operator=( pol3P) ;
|
|
Derive() ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void
|
|
PolynomialPoint3d::AdjustDegree( void)
|
|
{
|
|
// se il coefficiente del grado più alto è zero, diminuisco il grado
|
|
while ( m_nDegree >= 0 &&
|
|
abs( m_Coeff[m_nDegree].x) < DBL_EPSILON &&
|
|
abs( m_Coeff[m_nDegree].y) < DBL_EPSILON &&
|
|
abs( m_Coeff[m_nDegree].z) < DBL_EPSILON) {
|
|
m_Coeff.pop_back() ;
|
|
-- m_nDegree ;
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
Point3d
|
|
PolynomialPoint3d::Evaluate( double dVal)
|
|
{
|
|
// polinomio non inizializzato
|
|
if ( m_nDegree < 0)
|
|
return Point3d( 0, 0, 0) ;
|
|
// caso normale
|
|
Point3d ptRes = m_Coeff[m_nDegree] ;
|
|
for ( int i = m_nDegree - 1 ; i >= 0 ; -- i)
|
|
ptRes = ptRes * dVal + m_Coeff[i] ;
|
|
|
|
return ptRes ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int
|
|
PolynomialPoint3d::FindMainComponentRoots( DBLVECTOR& vdRoot)
|
|
{
|
|
// cerco la componente più significativa tra x, y e z
|
|
Point3d ptSumm ;
|
|
for ( int i = 0 ; i <= m_nDegree ; ++ i) {
|
|
ptSumm.x += abs( m_Coeff[i].x) ;
|
|
ptSumm.y += abs( m_Coeff[i].y) ;
|
|
ptSumm.z += abs( m_Coeff[i].z) ;
|
|
}
|
|
// la copio in un polinomio numerico
|
|
Polynomial polP ;
|
|
if ( ! polP.SetDegree( m_nDegree))
|
|
return 0 ;
|
|
if ( ptSumm.x > ptSumm.y && ptSumm.x > ptSumm.z) {
|
|
for ( int i = 0 ; i <= m_nDegree ; ++ i)
|
|
polP.SetCoeff( i, m_Coeff[i].x) ;
|
|
}
|
|
else if ( ptSumm.y > ptSumm.z) {
|
|
for ( int i = 0 ; i <= m_nDegree ; ++ i)
|
|
polP.SetCoeff( i, m_Coeff[i].y) ;
|
|
}
|
|
else {
|
|
for ( int i = 0 ; i <= m_nDegree ; ++ i)
|
|
polP.SetCoeff( i, m_Coeff[i].z) ;
|
|
}
|
|
// calcolo le radici reali di questo polinomio numerico
|
|
return polP.FindRoots( vdRoot) ;
|
|
} |