//---------------------------------------------------------------------------- // EgalTech 2014-2014 //---------------------------------------------------------------------------- // File : PolygonPlane.cpp Data : 12.08.14 Versione : 1.5h3 // Contenuto : Implementazione della classe PolygonPlane. // Calcolo della normale e delle aree con il metodo di Newell. // // // Modifiche : 12.08.14 DS Creazione modulo. // // //---------------------------------------------------------------------------- //--------------------------- Include ---------------------------------------- #include "stdafx.h" #include "PolygonPlane.h" //---------------------------------------------------------------------------- void PolygonPlane::AddPoint( const Point3d& ptP) { // se č il primo punto (parto da -1 perchč verrā contato alla chiusura) if ( m_nPntNbr == -1) m_ptFirst = ptP ; // dal secondo punto posso cominciare ad eseguire le somme parziali else { // Compute normal as being proportional to projected areas of polygon onto the yz, // xz, and xy planes. Also compute centroid as representative point on the plane m_vtN.x += ( m_ptLast.y - ptP.y) * ( m_ptLast.z + ptP.z) ; // projection on yz m_vtN.y += ( m_ptLast.z - ptP.z) * ( m_ptLast.x + ptP.x) ; // projection on xz m_vtN.z += ( m_ptLast.x - ptP.x) * ( m_ptLast.y + ptP.y) ; // projection on xy m_ptCen += ptP ; } // salvo punto e incremento numero di punti m_ptLast = ptP ; ++ m_nPntNbr ; } //---------------------------------------------------------------------------- bool PolygonPlane::Finalize( void) { // almeno 3 punti (il triangolo č il poligono con minimo numero di lati) if ( m_nPntNbr < 3) return false ; // se il poligono non č stato chiuso, aggiungo calcolo per ultimo lato if ( ! AreSamePointApprox( m_ptFirst, m_ptLast)) { // aggiungo il primo punto per far eseguire i conti sul lato di chiusura AddPoint( m_ptFirst) ; } // se non effettuato, eseguo il calcolo finale if ( m_dLenN < EPS_SMALL) { // lunghezza della normale (doppio dell'area del poligono) m_dLenN = m_vtN.Len() ; if ( m_dLenN < EPS_SMALL) return false ; // normalizzo m_vtN /= m_dLenN ; // sistemo baricentro m_ptCen /= m_nPntNbr ; } return true ; } //---------------------------------------------------------------------------- bool PolygonPlane::GetPlane( Plane3d& plPlane) { // verifico completamento conti if ( ! Finalize()) return false ; // assegno i dati al piano plPlane.vtN = m_vtN ; plPlane.dDist = ( ( m_ptCen - ORIG) * plPlane.vtN) ; return true ; } //---------------------------------------------------------------------------- bool PolygonPlane::GetArea( double& dArea) { // verifico completamento conti if ( ! Finalize()) return false ; // assegno l'area dArea = 0.5 * m_dLenN ; return true ; }