shape_doc 0.1
|
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