shape_doc 0.1
/Users/mourrain/Devel/mmx/shape/src/ssi_qnode.cpp
Go to the documentation of this file.
00001 #include <shape/ssi_qnode.hpp>
00002 namespace mmx {
00003 namespace  shape_ssi {    
00004 
00005   std::ostream& operator<<( std::ostream& o, const qnode & q )
00006   {
00007     o << "[ " << q.umin << ", " << q.umax << " ] x ";
00008     o << "[ " << q.vmin << ", " << q.vmax << " ]";
00009     return o;
00010   };
00011   
00012   void qnode::split_u() 
00013   {
00014     l = new qnode();
00015     r = new qnode();
00016     l->umin = umin;  
00017     l->umax = (umin+umax)/2;
00018     r->umin = (umin+umax)/2;
00019     r->umax = umax;
00020     l->vmin = r->vmin = vmin;
00021     l->vmax = r->vmax = vmax;
00022     l->father = r->father = this;
00023   };
00024 
00025 void qnode::split_v()
00026 {
00027   l = new qnode();
00028   r = new qnode();
00029   l->vmin = vmin;
00030   l->vmax = (vmin+vmax)/2;
00031   r->vmin = l->vmax;
00032   r->vmax = vmax;
00033   l->umin = r->umin = umin;
00034   l->umax = r->umax = umax;
00035   l->father = this;
00036   r->father = this;
00037 };
00038 
00039 
00040 qnode::~qnode()
00041 {
00042   if  (l ) delete l;
00043   if ( r ) delete r;
00044 };
00045 
00046 void qnode::fill( vector3 ** qp, sample *  s  ) const
00047 {
00048   qp[0] = s->base() + this->umin*s->m_ncols + this->vmin;
00049   qp[1] = s->base() + this->umax*s->m_ncols + this->vmin;
00050   qp[2] = qp[1]  + this->vmax - this->vmin;
00051   qp[3] = qp[0]  + this->vmax - this->vmin;
00052 };
00053 
00054 void qnode::split( sample * s)
00055 {
00056 
00057   if ( l ) return;
00058   if ( du(this) > dv(this) ) 
00059     {
00060       this->split_u();
00061       l->mbox(s);
00062       r->mbox(s);
00063     }
00064   else if ( dv(this) > 1 ) 
00065     {
00066       this->split_v();
00067       l->mbox(s);
00068       r->mbox(s);
00069     };
00070 
00071 };
00072 
00073 void qnode::mbox( sample * s )
00074 {
00075   vector3 * qp[4];
00076   fill( qp, s );
00077   for ( int i = 0; i < 3; i ++ ) box[i].m = box[i].M = qp[0]->data[i];
00078   for ( int i = 1; i < 4; i ++ )
00079     for ( int d = 0; d < 3; d ++ )
00080       {
00081         if ( qp[i]->data[d] < box[d].m ) box[d].m = qp[i]->data[d];
00082         else {  if ( qp[i]->data[d] > box[d].M ) box[d].M = qp[i]->data[d]; };
00083       };
00084 };
00085  
00086 void qnode::fill( vector3   *qp, sample * s  ) const
00087 {
00088   vector3  *r = s->base() + this->umin*s->m_ncols + this->vmin;
00089   qp[0] = *r;
00090   qp[3] = *(r + this->vmax - this->vmin);
00091   r = s->base() + this->umax*s->m_ncols + this->vmin;
00092   qp[1] = *r;
00093   qp[2] = *(r + this->vmax - this->vmin);
00094 };
00095 
00096 qnode * search( coord_t u, coord_t v, qnode * start )
00097 {
00098   qnode * tmp = start;
00099   do { tmp=tmp->father; } while(tmp && !inside(u,v,tmp) );
00100   if ( !tmp ) return 0;
00101   while(1){ 
00102     if ( leaf(tmp) ) return tmp;
00103     if ( inside(u,v,tmp->l) ) { tmp = tmp->l; continue; };
00104     if ( inside(u,v,tmp->r) ) { tmp = tmp->r; continue; };
00105     return 0;
00106   };
00107 };
00108 
00109 
00110 void qnode::convert( vector2 * p, sample * s, int n  ) const 
00111 {
00112   assert(du(this)==1 && dv(this)==1);
00113   double u = s->uvalue(umin);
00114   double v = s->vvalue(vmin);
00115   double vu = s->uvalue(umax)-u;
00116   double vv = s->vvalue(vmax)-v;
00117   for ( int i = 0; i < n; i ++ )
00118     {
00119       p[i][0] = u + p[i][0]*vu; 
00120       p[i][1] = v + p[i][1]*vv;
00121     };
00122 };
00123 
00124 }
00125 } //namespace mmx
00126        
00127