amr3t.cpp

Go to the documentation of this file.
00001 /*
00002 **
00003 ** File: martree.cpp
00004 **
00005 ** Author: Mauricio Riguette Mediano
00006 **
00007 ** Date: 28/03/1997
00008 **
00009 */
00010 
00011 #include <math.h>
00012 #include <string.h>
00013 #include <stdio.h>
00014 #include <stdlib.h>
00015 #include <float.h>
00016 
00017 #include "amr3t.h"
00018 
00019 // -------------------------------------------
00020 void PFS3Box::Dup(PFS3Box *B)
00021 {
00022   Xmin = B->Xmin;
00023   Ymin = B->Ymin;
00024   Zmin = B->Zmin;
00025   Xmax = B->Xmax;
00026   Ymax = B->Ymax;
00027   Zmax = B->Zmax;
00028 }
00029 // -------------------------------------------
00030 int PFS3Box::Equal(PFS3Box *B) 
00031 {
00032   return( Xmin==B->Xmin&&Ymin==Ymin&&Zmin==Zmin&& 
00033           Xmax==B->Xmax&&Ymax==Ymax&&Zmax==Zmax);
00034 }
00035 // -------------------------------------------
00036 int PFS3Box::Disjoint(PFS3Box *B) 
00037 {
00038   if( Xmax<B->Xmin||Xmin>B->Xmax|| 
00039       Ymax<B->Ymin||Ymin>B->Ymax|| 
00040       Zmax<B->Zmin||Zmin>B->Zmax)
00041     return(1);
00042   return(0);
00043 }
00044 // -------------------------------------------
00045 double PFS3Box::Volume() 
00046 {
00047   return((Xmax-Xmin)*(Ymax-Ymin)*(Zmax-Zmin));
00048 }
00049 // -------------------------------------------
00050 void PFS3Box::ExtendVolume(PFS3Box *B)
00051 {
00052   Xmin = MIN(Xmin,B->Xmin);
00053   Ymin = MIN(Ymin,B->Ymin);
00054   Zmin = MIN(Zmin,B->Zmin);
00055   Xmax = MAX(Xmax,B->Xmax);
00056   Ymax = MAX(Ymax,B->Ymax);
00057   Zmax = MAX(Zmax,B->Zmax);
00058 }
00059 // --------------------------------------------------------
00060 PFS3NodeBoxId::PFS3NodeBoxId(int Pmin, int Pmax) 
00061 { 
00062   if(Pmin>Pmax) exit(1);
00063   Min = Pmin;
00064   Max = Pmax;
00065   Num=0;
00066   Vet = new PFS3BoxId[Max+1];
00067   if(Vet==NULL) exit(1);
00068 }
00069 // --------------------------------------------------------
00070 PFS3NodeBoxId::~PFS3NodeBoxId()
00071 {
00072   delete[] Vet;
00073 }
00074 // --------------------------------------------------------
00075 void PFS3NodeBoxId::Dup(PFS3NodeBoxId* Fromn)
00076 {
00077   int i;
00078   Num=Fromn->Num;
00079   Max=Fromn->Max;
00080   Min=Fromn->Min;
00081   if (Vet!=NULL) delete[] Vet;
00082   if (Fromn->Vet==NULL) {
00083     Vet=NULL;
00084     return;
00085   };
00086   Vet = new PFS3BoxId[Max+1];
00087   if(Vet==NULL) exit(1);
00088   for(i=0;i<Num;i++)
00089     Vet[i]=Fromn->Vet[i];
00090 };
00091 // --------------------------------------------------------
00092 void PFS3NodeBoxId::BBox(PFS3Box *B)
00093 {
00094   if (Num==0) exit(1);
00095   *B = Vet[0];
00096   for(int cont=1;cont<Num;cont++)
00097     B->ExtendVolume(&Vet[cont]);
00098 };
00099 // --------------------------------------------------------
00100 void PFS3NodeBoxId::MakeBoxId(PFS3BoxId *E)
00101 {
00102   BBox(E);
00103   E->P=this;
00104 }
00105 // --------------------------------------------------------
00106 void PFS3NodeBoxId::GetPos(PFS3BoxId *E,int i)
00107 {
00108   if (Vet==NULL) exit(1);
00109   if (i > Num) exit(1);
00110   *E = Vet[i];
00111 };
00112 // --------------------------------------------------------
00113 void PFS3NodeBoxId::PutPos(PFS3BoxId *E,int i)
00114 {
00115   if(Vet==NULL) exit(1);
00116   if(i > Num) exit(1);
00117   Vet[i]=*E;
00118 };
00119 // --------------------------------------------------------
00120 void PFS3NodeBoxId::Insert(PFS3BoxId *E,int Posit)
00121 {
00122   if(Vet==NULL) exit(1);
00123   if(Posit>Num) exit(1);
00124   for(int cont=Num;cont>Posit;cont--)
00125     Vet[cont]=Vet[cont-1];
00126   Num++;
00127   Vet[Posit]=*E;
00128 };
00129 // --------------------------------------------------------
00130 void PFS3NodeBoxId::Append(PFS3BoxId *E)
00131 {
00132   if(Num > Max) exit(1);
00133   PutPos(E,Num);
00134   Num++;
00135 };
00136 // --------------------------------------------------------
00137 void PFS3NodeBoxId::Remove(int i)
00138 {
00139   if (Vet==NULL) exit(1);
00140   if (i > Num) exit(1);
00141   Num--;
00142   for(int cont=i;cont<Num;cont++)
00143     Vet[cont]=Vet[cont+1];
00144 };
00145 // --------------------------------------------------------
00146 void PFS3NodeBoxId::Remove(PFS3BoxId *E,int Cont)
00147 {
00148   GetPos(E,Cont);
00149   Remove(Cont);
00150 };
00151 // --------------------------------------------------------
00152 void PFS3NodeBoxId::Remove(PFS3BoxId *E)
00153 {
00154   GetPos(E,Num-1);
00155   Num--;
00156 }
00157 // --------------------------------------------------------
00158 void PFS3NodeBoxId::ChooseBoxId(PFS3BoxId *Loc,PFS3BoxId *Out,int *Posit)
00159 {
00160   PFS3BoxId eaux;
00161   double smallerarea,areabefore;
00162 
00163   if (Num==0) exit(1);
00164   *Posit=0;
00165   GetPos(&eaux,*Posit);
00166   *Out = eaux;
00167   areabefore = eaux.Volume()+Loc->Volume();
00168   eaux.ExtendVolume(Loc);
00169   smallerarea = eaux.Volume() - areabefore;
00170   for(int cont=1;cont<Number();cont++) {
00171     GetPos(&eaux,cont);
00172     areabefore = eaux.Volume()+Loc->Volume();
00173     eaux.ExtendVolume(Loc);
00174     if(eaux.Volume() - areabefore < smallerarea) {
00175       GetPos(Out,cont);
00176       *Posit = cont;
00177       smallerarea = eaux.Volume() - areabefore;
00178     }
00179   }
00180 }
00181 // --------------------------------------------------------
00182 void PFS3NodeBoxId::UpdateBox(PFS3Box *B,int Posit)
00183 {
00184   PFS3BoxId E;
00185   GetPos(&E,Posit);
00186   E.Dup(B);
00187   PutPos(&E,Posit);
00188 }
00189 // --------------------------------------------------------
00190 int PFS3NodeBoxId::LocateBoxId(PFS3BoxId *In,int *Posit)
00191 {
00192   for(int cont=0;cont<Number();cont++)
00193     if(Vet[cont].P==In->P) {
00194       *Posit=cont;
00195       return(0);
00196     }
00197   return(1);
00198 }
00199 // --------------------------------------------------------
00200 void PFS3NodeBoxId::SplitNodeR3tree(PFS3NodeBoxId *Newnode)
00201 {
00202   PFS3NodeBoxId auxnode(Min,Max);
00203   double extraarea;
00204   double areabefore;
00205   int imax, jmax;
00206   int i, j;
00207   PFS3BoxId ei, ej;
00208   PFS3BoxId eiaux,ejaux;
00209 
00210   imax=0;       //Inicializa entradas
00211   jmax=1;
00212   GetPos(&eiaux, 0); 
00213   GetPos(&ejaux, 1);
00214   areabefore = eiaux.Volume() + ejaux.Volume();
00215   eiaux.ExtendVolume(&ejaux);
00216   extraarea = eiaux.Volume() - areabefore;
00217 
00218   for(i=0;i<Number();i++) {  // Escolhe entradas iniciais.
00219     for(j=i+1;j<Number();j++) {
00220       GetPos(&eiaux, i);
00221       GetPos(&ejaux, j);
00222       areabefore = eiaux.Volume() + ejaux.Volume();
00223       eiaux.ExtendVolume(&ejaux);
00224       if(eiaux.Volume() - areabefore > extraarea) {
00225         imax = i;
00226         jmax = j;
00227         extraarea = eiaux.Volume() - areabefore;
00228       };
00229     } /* endfor */
00230   } /* endfor */
00231 
00232   if(imax>jmax) {
00233     Remove(&ei, imax);
00234     Remove(&ej, jmax);
00235   } else {
00236     Remove(&ej, jmax);
00237     Remove(&ei, imax);
00238   }
00239 
00240   while(Number()>0) {  // Move entradas para no' auxiliar.
00241     PFS3BoxId E;
00242     Remove(&E);
00243     auxnode.Append(&E);
00244   } /* endfor */
00245 
00246   Append(&ei);
00247   Newnode->Append(&ej);
00248   for(i=0;i<Min-1;i++) {  // Insere minimo por no'.
00249     PFS3BoxId E;
00250     int choose;
00251     auxnode.ChooseBoxId(&ei,&E,&choose);
00252     auxnode.Remove(&E, choose);
00253     ei.ExtendVolume(&E);
00254     Append(&E);
00255     auxnode.ChooseBoxId(&ej,&E,&choose);
00256     auxnode.Remove(&E, choose);
00257     ej.ExtendVolume(&E);
00258     Newnode->Append(&E);
00259   } /* endfor */
00260 
00261   GetPos(&ei,0);
00262   Newnode->GetPos(&ej,0);
00263   while(auxnode.Number()>0) {
00264     PFS3BoxId E;
00265     PFS3Box biaux,bjaux;
00266     auxnode.Remove(&E);
00267     biaux = ei;
00268     biaux.ExtendVolume(&E);
00269     bjaux = ej;
00270     bjaux.ExtendVolume(&E);
00271     if(biaux.Volume()-ei.Volume()<
00272        bjaux.Volume()-ej.Volume()){
00273       Append(&E);
00274       ei.ExtendVolume(&E);
00275     } else {
00276       Newnode->Append(&E);
00277       ej.ExtendVolume(&E);
00278     }
00279   } /* endfor */
00280 }
00281 // --------------------------------------------------------
00282 PFS3Rtree::PFS3Rtree(int Nmin,int Nmax)
00283 {
00284   Min=Nmin;
00285   Max=Nmax;
00286 }
00287 // --------------------------------------------------------
00288 PFS3Rtree::~PFS3Rtree()
00289 {
00290 }
00291 // --------------------------------------------------------
00292 void PFS3Rtree::MergeRoot()
00293 {
00294   PFS3BoxId enode;
00295   Root->GetPos(&enode,0);
00296   delete Root;
00297   Root=(PFS3NodeBoxId *)enode.P;
00298 }
00299 // --------------------------------------------------------
00300 void PFS3Rtree::BBox(PFS3Box *B)
00301 {
00302   Root->BBox(B);
00303 }
00304 // --------------------------------------------------------
00305 int PFS3Rtree::Remove(PFS3BoxId *newentry)
00306 {
00307   if (Remove(Root,newentry,Level)==2) return(2);
00308   if (Level>0 && Root->Number()==1){
00309     MergeRoot();
00310     Level--;
00311   }
00312   return(0);
00313 };
00314 // --------------------------------------------------------
00315 int PFS3Rtree::Remove(PFS3NodeBoxId *Node,PFS3BoxId *In,int Lev)
00316 {
00317   int posit;
00318   if (Lev==0) {
00319     if(Node->LocateBoxId(In,&posit)==0) {
00320       Node->Remove(posit);
00321       return(0);
00322     };
00323   } else {
00324     PFS3BoxId eson;
00325     PFS3NodeBoxId *son;
00326     for(posit=0;posit<Node->Number();posit++) {
00327       Node->GetPos(&eson,posit);
00328       if (In->Disjoint(&eson))
00329         continue;
00330       son=(PFS3NodeBoxId *)eson.P;
00331       if(Remove(son,In,Lev-1)==2) {
00332         continue;
00333       } else if(son->Number()<Min) {
00334         Merge(Node,son,posit);
00335       } else {
00336         son->MakeBoxId(&eson);
00337         Node->PutPos(&eson,posit);
00338       };
00339       return(0);
00340     }
00341   };
00342   return(2);
00343 }
00344 // --------------------------------------------------------
00345 void PFS3Rtree::Insert(PFS3BoxId *newentry)
00346 {
00347   PFS3BoxId out;
00348   if(Insert(Root,newentry,&out,Level)==2) {
00349     PFS3BoxId oldentry;
00350     PFS3NodeBoxId *newroot= new PFS3NodeBoxId(Min,Max);
00351     if (newroot==NULL) exit(1);
00352     Root->MakeBoxId(&oldentry);
00353     newroot->Append(&oldentry);
00354     newroot->Append(&out);
00355     Root=newroot;
00356     Level++;
00357   } /* endif */
00358 }
00359 // --------------------------------------------------------
00360 void PFS3Rtree::SplitNodeR3tree(PFS3NodeBoxId *Node, PFS3BoxId *Out)
00361 {
00362   PFS3NodeBoxId *newnode= new PFS3NodeBoxId(Min,Max);
00363   if (newnode==NULL) exit(1);
00364   Node->SplitNodeR3tree(newnode);
00365   newnode->MakeBoxId(Out);
00366 };
00367 // --------------------------------------------------------
00368 int PFS3Rtree::Insert(PFS3NodeBoxId *Node,PFS3BoxId *In,PFS3BoxId *Out,int Lev)
00369 {
00370   if (Lev==0) {
00371     Node->Append(In);
00372     if (Node->Number() > Max) {
00373       SplitNodeR3tree(Node,Out);
00374       return(2);
00375     }
00376   } else {
00377     int status,posit;
00378     PFS3BoxId eson;
00379     PFS3NodeBoxId *son;
00380     Node->ChooseBoxId(In,&eson,&posit);
00381     son=(PFS3NodeBoxId *)eson.P;
00382     status = Insert(son,In,Out,Lev-1);
00383     son->MakeBoxId(&eson);
00384     Node->PutPos(&eson,posit);
00385     if (status==2) {
00386       Node->Append(Out);
00387       if(Node->Number() > Max) {
00388         SplitNodeR3tree(Node,Out);
00389         return(2);
00390       }
00391     }
00392   }
00393   return(0);
00394 }
00395 // --------------------------------------------------------
00396 void PFS3Rtree::Merge(PFS3NodeBoxId *Father,PFS3NodeBoxId *Node,short Posit)
00397 {
00398 
00399 //
00400 // Alterar para procurar o no' mais proximo para 
00401 // fazer o merge.
00402 //
00403 
00404   int i;
00405   PFS3BoxId auxentry;
00406   PFS3NodeBoxId *auxnode;
00407   PFS3BoxId eaux;
00408   short auxposit;
00409   if(Posit + 1 < Father->Number()) auxposit = Posit + 1;
00410   else if(Posit > 0) auxposit = Posit - 1;
00411   Father->GetPos(&auxentry,auxposit);
00412   auxnode=(PFS3NodeBoxId *)auxentry.P;
00413   if(auxnode->Number() + Node->Number() <= Max) {
00414     for(i=0;i<Node->Number();i++) {
00415       Node->GetPos(&eaux,i);
00416       auxnode->Append(&eaux);
00417     }
00418     auxnode->MakeBoxId(&auxentry);
00419     Father->PutPos(&auxentry,auxposit);
00420     delete(Node);
00421     Father->Remove(Posit);
00422   } else {
00423     while(Node->Number() < Min) {
00424       auxnode->Remove(&eaux);
00425       Node->Append(&eaux);
00426     }
00427     auxnode->MakeBoxId(&auxentry);
00428     Father->PutPos(&auxentry,auxposit);
00429     Node->MakeBoxId(&auxentry);
00430     Father->PutPos(&auxentry,Posit);
00431   }
00432 }
00433 // --------------------------------------------------------
00434 void PFS3Rtree::Create()
00435 {
00436   Root=new PFS3NodeBoxId(Min,Max);
00437   if (Root==NULL) exit(1);
00438   Level=0;
00439 }
00440 // --------------------------------------------------------
00441 void PFS3Rtree::Delete()
00442 {
00443   if (Level>0)
00444     Delete(Root,Level);
00445   delete (Root);
00446 };
00447 // --------------------------------------------------------
00448 void PFS3Rtree::Delete(PFS3NodeBoxId *Node,int Lev)
00449 {
00450   if (Lev>0) {
00451     PFS3BoxId e;
00452     PFS3NodeBoxId *naux;
00453     while(Node->Number()>0) {
00454       Node->Remove(&e);
00455       naux=(PFS3NodeBoxId *)e.P;
00456       Delete(naux,Lev-1);
00457       delete(naux);
00458     }
00459   }
00460 }
00461 // --------------------------------------------------------
00462 int PFS3Rtree::Number()
00463 {
00464   int num=0;
00465   Number(Root,&num,Level);
00466   return(num);
00467 };
00468 // --------------------------------------------------------
00469 void PFS3Rtree::Number(PFS3NodeBoxId *Node,int *Num,int Lev)
00470 {
00471   PFS3BoxId e;
00472   if (Lev==0) { 
00473     *Num += Node->Number();
00474   } else {
00475     PFS3NodeBoxId *naux;
00476     while(Node->Number()>0) {
00477       Node->Remove(&e);
00478       naux=(PFS3NodeBoxId *)e.P;
00479       Number(naux,Num,Lev-1);
00480     }
00481   }
00482 }
00483 // --------------------------------------------------------
00484 void PFS3Rtree::Print()
00485 {
00486   int num=0;
00487   Print(Root,0,&num,Level);
00488   printf("Numero de elementos %d\n", num);
00489 }
00490 // --------------------------------------------------------
00491 void PFS3Rtree::Print( PFS3NodeBoxId *Node, int ident, int *Num, int Lev)
00492 {
00493   PFS3BoxId e;
00494   int i,j;
00495   PFS3Box* vet;
00496   vet = new PFS3Box[Max];
00497   if(vet==NULL) exit(1);
00498   for( i=0;i<ident;i++) {    
00499     printf( " ");
00500   }
00501   printf( "No #%d ->\n", Node->Number());
00502   for( i=0;i<Node->Number();i++) { 
00503     Node->GetPos(& e, i);
00504     e.Dup(&vet[i]);
00505     for( j=0;j<ident+2;j++) {    
00506       printf( " ");
00507     }
00508     printf("#%d %g %g %g %g %g %g\n",i, vet[i].Xmin, vet[i].Ymin, vet[i].Zmin,
00509                                         vet[i].Xmax, vet[i].Ymax, vet[i].Zmax);
00510   }
00511   if (Lev==0) {
00512     *Num+=Node->Number();
00513   } else {
00514     PFS3NodeBoxId *naux;
00515     for( i=0;i<Node->Number();i++) { 
00516       PFS3Box B;
00517       Node->GetPos(& e, i);
00518       naux=(PFS3NodeBoxId *)e.P;
00519       naux->BBox(&B);
00520       if(!B.Equal(&vet[i])) printf( "\nErro Box\n");
00521       Print(naux, ident+2, Num, Lev -1);
00522     }
00523   }
00524   delete[] vet;
00525 }
00526 // --------------------------------------------------------
00527 void PFS3Rtree::Search(PFS3Box *B)
00528 {
00529   Vnode[0]=Root;
00530   Vpos[0]=0;
00531   NumL=0;
00532   SearchVal=*B;
00533 };
00534 // --------------------------------------------------------
00535 int PFS3Rtree::Result(PFS3BoxId *B)
00536 {
00537   PFS3BoxId currkey;
00538   for(;;) {
00539     for (;Vpos[NumL]<Vnode[NumL]->Number();Vpos[NumL]++) {
00540       Vnode[NumL]->GetPos(&currkey,Vpos[NumL]);
00541       if (!currkey.Disjoint(&SearchVal))
00542           break;
00543     }
00544     if (Vpos[NumL]==Vnode[NumL]->Number()) {
00545       NumL--;
00546       if (NumL<0) break;
00547       else Vpos[NumL]++;
00548     } else {
00549       Vnode[NumL]->GetPos(&currkey,Vpos[NumL]);
00550       if (NumL==Level) break;
00551       NumL++;
00552       Vnode[NumL]=(PFS3NodeBoxId *)currkey.P;
00553       Vpos[NumL]=0;
00554     }
00555   }
00556   if (NumL==-1) return(1);
00557   *B=currkey;
00558   Vpos[NumL]++;
00559   return(0);
00560 };
00561 // --------------------------------------------------------
00562 void PFS3Rtree::SearchAll()
00563 {
00564   Vnode[0]=Root;
00565   Vpos[0]=0;
00566   NumL=0;
00567 };
00568 // --------------------------------------------------------
00569 int PFS3Rtree::ResultAll(PFS3BoxId *B)
00570 {
00571   PFS3BoxId currkey;
00572   for(;;) {
00573     Vnode[NumL]->GetPos(&currkey,Vpos[NumL]);
00574     if (Vpos[NumL]==Vnode[NumL]->Number()) {
00575       NumL--;
00576       if (NumL<0) break;
00577       else Vpos[NumL]++;
00578     } else {
00579       Vnode[NumL]->GetPos(&currkey,Vpos[NumL]);
00580       if (NumL==Level) break;
00581       NumL++;
00582       Vnode[NumL]=(PFS3NodeBoxId *)currkey.P;
00583       Vpos[NumL]=0;
00584     };
00585   };
00586   if (NumL==-1) return(1);
00587   *B=currkey;
00588   Vpos[NumL]++;
00589   return(0);
00590 };
00591 // --------------------------------------------------------

Generated on Tue Oct 23 11:23:28 2007 for Relax by  doxygen 1.5.3