00001
00002
00003
00004
00005
00006
00007
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;
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++) {
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 }
00230 }
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) {
00241 PFS3BoxId E;
00242 Remove(&E);
00243 auxnode.Append(&E);
00244 }
00245
00246 Append(&ei);
00247 Newnode->Append(&ej);
00248 for(i=0;i<Min-1;i++) {
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 }
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 }
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 }
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
00401
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