00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #include <CompuCell3D/Field3D/Point3D.h>
00040 #include <CompuCell3D/Field3D/Dim3D.h>
00041
00042 #include <CompuCell3D/Field3D/Neighbor.h>
00043 #include <CompuCell3D/Field3D/NeighborFinder.h>
00044 #include <map>
00045 #include <Utils/Coordinates3D.h>
00046
00047 #define EXP_STL
00048 #include "BoundaryStrategy.h"
00049 #include <CompuCell3D/Field3D/Field3DImpl.h>
00050
00051 #include "Boundary.h"
00052 #include "BoundaryFactory.h"
00053
00054 #include "AlgorithmFactory.h"
00055 #include "Algorithm.h"
00056
00057
00058
00059
00060
00061 using namespace std;
00062 using namespace CompuCell3D;
00063
00064
00065 BoundaryStrategy* BoundaryStrategy::singleton;
00066
00067
00068
00069 BoundaryStrategy::BoundaryStrategy(){
00070
00071 strategy_x = BoundaryFactory::createBoundary(BoundaryFactory::no_flux);
00072 strategy_y = BoundaryFactory::createBoundary(BoundaryFactory::no_flux);
00073 strategy_z = BoundaryFactory::createBoundary(BoundaryFactory::no_flux);
00074 algorithm = AlgorithmFactory::createAlgorithm(AlgorithmFactory::Default,0,0,"None");
00075
00076 regular = true;
00077 neighborListsInitializedFlag=false;
00078 latticeType=SQUARE_LATTICE;
00079
00080 unsigned int maxHexArraySize=(Y_ODD|Z_ODD|X_ODD|Y_EVEN|Z_EVEN|X_EVEN)+1;
00081 cerr<<"maxHexArraySize="<<maxHexArraySize<<endl;
00082
00083 cerr<<"\t\t\t\t\t\t\t CALLING DEFAULT CONSTRUCTOR FOR BOUNDARY STRATEGY"<<endl;
00084
00085
00086 }
00087
00088
00089
00090 BoundaryStrategy::BoundaryStrategy(string boundary_x, string boundary_y,
00091 string boundary_z, string alg, int index, int size, string inputfile,LatticeType latticeType)
00092
00093 {
00094
00095 strategy_x = BoundaryFactory::createBoundary(boundary_x);
00096 strategy_y = BoundaryFactory::createBoundary(boundary_y);
00097 strategy_z = BoundaryFactory::createBoundary(boundary_z);
00098 algorithm = AlgorithmFactory::createAlgorithm(alg, index, size, inputfile);
00099 regular = true;
00100 neighborListsInitializedFlag=false;
00101 this->latticeType=latticeType;
00102
00103 unsigned int maxHexArraySize=(Y_ODD|Z_ODD|X_ODD|Y_EVEN|Z_EVEN|X_EVEN)+1;
00104 cerr<<"\t\t\t\t\t\t\t CALLING SPECILIZED CONSTRUCTOR FOR BOUNDARY STRATEGY"<<endl;
00105 cerr<<"maxHexArraySize="<<maxHexArraySize<<endl;
00106
00107
00108 }
00109
00110
00111 BoundaryStrategy::~BoundaryStrategy() {
00112
00113 delete strategy_x;
00114 delete strategy_y;
00115 delete strategy_z;
00116
00117 singleton = 0;
00118
00119 }
00120
00121
00122 LatticeMultiplicativeFactors BoundaryStrategy::generateLatticeMultiplicativeFactors(LatticeType _latticeType,Dim3D dim){
00123 LatticeMultiplicativeFactors lFactors;
00124 if(_latticeType==HEXAGONAL_LATTICE){
00125 if(dim.x==1 ||dim.y==1 || dim.z==1){
00126
00127
00128 lFactors.volumeMF=1.0;
00129 lFactors.surfaceMF=sqrt(2.0/(3.0*sqrt(3.0)));
00130 lFactors.lengthMF=lFactors.surfaceMF*sqrt(3.0);
00131 return lFactors;
00132 }else{
00133
00134
00135
00136 lFactors.volumeMF=1.0;
00137 lFactors.surfaceMF=8.0/12.0*sqrt(2.0)*pow(9.0/(16.0*sqrt(3.0)),1.0/3.0)*pow(9.0/(16.0*sqrt(3.0)),1.0/3.0);
00138 lFactors.lengthMF=2.0*sqrt(2.0/3.0)*pow(9.0/(16.0*sqrt(3.0)),1.0/3.0);
00139 return lFactors;
00140 }
00141 }else{
00142 lFactors.volumeMF=1.0;
00143 lFactors.surfaceMF=1.0;
00144 lFactors.lengthMF=1.0;
00145 return lFactors;
00146 }
00147 }
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157 bool BoundaryStrategy::isValid(const Point3D &pt) const {
00158
00159
00160
00161
00162
00163
00164
00165
00166 if (0 <= pt.x && pt.x < dim.x &&
00167 0 <= pt.y && pt.y < dim.y &&
00168 0 <= pt.z && pt.z < dim.z ) {
00169 return algorithm->inGrid(pt);
00170 }
00171
00172 return false;
00173 }
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184 bool BoundaryStrategy::isValid(const int coordinate, const int max_value) {
00185
00186 return (0 <= coordinate && coordinate < max_value);
00187 }
00188
00189
00190
00191
00192
00193
00194 void BoundaryStrategy::setDim(const Dim3D theDim) {
00195
00196 Dim3D oldDim(dim);
00197
00198 dim = theDim;
00199 algorithm->setDim(theDim);
00200 if(! neighborListsInitializedFlag){
00201 prepareNeighborLists();
00202 neighborListsInitializedFlag=true;
00203 }
00204
00205
00207
00208
00209
00210
00211 }
00212
00213
00214
00215
00216
00217
00218 void BoundaryStrategy::setCurrentStep(const int theCurrentStep) {
00219
00220 currentStep = theCurrentStep;
00221 algorithm->setCurrentStep(theCurrentStep);
00222
00223 }
00224
00225
00226
00227
00228
00229 void BoundaryStrategy::setIrregular() {
00230
00231 regular = false;
00232
00233 }
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246 Point3D BoundaryStrategy::getNeighbor(const Point3D& pt, unsigned int& token, double& distance, bool checkBounds)
00247 {
00248 Neighbor n;
00249 Point3D p;
00250 int x;
00251 int y;
00252 int z;
00253 bool x_bool;
00254 bool y_bool;
00255 bool z_bool;
00256
00257 NeighborFinder::destroy();
00258
00259 while(true)
00260 {
00261
00262 n = NeighborFinder::getInstance()->getNeighbor(token);
00263 x = (pt + n.pt).x;
00264 y = (pt + n.pt).y;
00265 z = (pt + n.pt).z;
00266
00267 token++;
00268
00269 if(!checkBounds || isValid(pt + n.pt))
00270 {
00271
00272 break;
00273 }
00274 else
00275 {
00276 if (regular)
00277 {
00278
00279 x_bool = (isValid(x,dim.x) ? true : strategy_x->applyCondition(x, dim.x));
00280 y_bool = (isValid(y,dim.y) ? true : strategy_y->applyCondition(y, dim.y));
00281 z_bool = (isValid(z,dim.z) ? true : strategy_z->applyCondition(z, dim.z));
00282
00283
00284
00285 if(x_bool && y_bool && z_bool)
00286 {
00287 break;
00288 }
00289 }
00290 }
00291 }
00292
00293 distance = n.distance;
00294 p.x = x;
00295 p.y = y;
00296 p.z = z;
00297
00298 return p;
00299
00300 }
00301
00302 int BoundaryStrategy::getNumPixels(int x, int y, int z) const {
00303
00304 return algorithm->getNumPixels(x, y, z);
00305
00306 }
00307
00308
00309
00310 bool BoundaryStrategy::checkIfOffsetAlreadyStacked(Point3D & _ptToCheck , std::vector<Point3D> & _offsetVec){
00311
00312 for(int i = 0 ; i < _offsetVec.size() ; ++i ){
00313 if( _offsetVec[i].x==_ptToCheck.x && _offsetVec[i].y==_ptToCheck.y && _offsetVec[i].z==_ptToCheck.z)
00314 return true;
00315 }
00316 return false;
00317 }
00318
00319 double BoundaryStrategy::calculateDistance(Coordinates3D<double> & _pt1 , Coordinates3D<double> & _pt2){
00320 return sqrt((double)(_pt1.x-_pt2.x)*(_pt1.x-_pt2.x)+(_pt1.y-_pt2.y)*(_pt1.y-_pt2.y)+(_pt1.z-_pt2.z)*(_pt1.z-_pt2.z));
00321 }
00322
00323 bool BoundaryStrategy::checkEuclidianDistance(Coordinates3D<double> & _pt1,Coordinates3D<double> & _pt2, float _distance){
00324
00325
00326 return calculateDistance(_pt1,_pt2)<_distance+0.1;
00327
00328 }
00329
00330
00331
00332
00333 bool BoundaryStrategy::precisionCompare(float _x,float _y,float _prec){
00334 return fabs(_x-_y)<_prec;
00335 }
00336
00337
00338 Coordinates3D<double> BoundaryStrategy::HexCoord(const Point3D & _pt){
00339
00340 if(_pt.z%2){
00341 if(_pt.y%2)
00342 return Coordinates3D<double>(_pt.x , sqrt(3.0)/2.0*(_pt.y+2.0/3.0), _pt.z*sqrt(6.0)/3.0 );
00343 else
00344 return Coordinates3D<double>( _pt.x+0.5 , sqrt(3.0)/2.0*(_pt.y+2.0/3.0) , _pt.z*sqrt(6.0)/3.0);
00345 }
00346 else{
00347 if(_pt.y%2)
00348 return Coordinates3D<double>(_pt.x , sqrt(3.0)/2.0*_pt.y, _pt.z*sqrt(6.0)/3.0 );
00349 else
00350 return Coordinates3D<double>( _pt.x+0.5 , sqrt(3.0)/2.0*_pt.y , _pt.z*sqrt(6.0)/3.0);
00351 }
00352 }
00353
00354
00355 Coordinates3D<double> BoundaryStrategy::calculatePointCoordinates(const Point3D & _pt){
00356 if(latticeType==HEXAGONAL_LATTICE){
00357 Coordinates3D<double> hexCoord=HexCoord(_pt);
00358 hexCoord.x*=lmf.lengthMF;
00359 hexCoord.y*=lmf.lengthMF;
00360 hexCoord.z*=lmf.lengthMF;
00361 return hexCoord;
00362 }else{
00363 return Coordinates3D<double>(_pt.x,_pt.y,_pt.z);
00364 }
00365
00366 }
00367
00368 void BoundaryStrategy::prepareNeighborListsHex(float _maxDistance){
00369
00370 cerr<<"INSIDE prepareNeighborListsHex"<<endl;
00371 unsigned int maxHexArraySize=(Y_ODD|Z_ODD|X_ODD|Y_EVEN|Z_EVEN|X_EVEN)+1;
00372
00373 hexOffsetArray.assign(maxHexArraySize,vector<Point3D>());
00374 hexDistanceArray.assign(maxHexArraySize,vector<float>());
00375 hexNeighborOrderIndexArray.assign(maxHexArraySize,vector<unsigned int>());
00376
00377 char a='0';
00378
00379 vector<Point3D> offsetVecTmp;
00380 vector<float> distanceVecTmp;
00381 Field3DImpl<char> tempField(dim,a);
00382 Point3D ctPt(dim.x/2,dim.y/2,dim.z/2);
00383
00384 Point3D ctPtTmp;
00385 unsigned int indexHex;
00386
00387
00388
00389 ctPtTmp=ctPt;
00390 indexHex=Y_EVEN|Z_EVEN;
00391 if(dim.z > 1){
00392 if( ctPtTmp.y % 2 ){
00393 ctPtTmp.y+1;
00394 }
00395 if( ctPtTmp.z % 2 )
00396 ctPtTmp.z+=1;
00397
00398 getOffsetsAndDistances(ctPtTmp,_maxDistance,tempField,hexOffsetArray[indexHex],hexDistanceArray[indexHex],hexNeighborOrderIndexArray[indexHex]);
00399
00400 }else{
00401 cerr<<"ctPtTmp.y % 2 ="<<ctPtTmp.y % 2 <<endl;
00402 if( ctPtTmp.y % 2 ){
00403 ctPtTmp.y+=1;
00404 }
00405 cerr<<"even even ctPtTmp="<<ctPtTmp<<endl;
00406 getOffsetsAndDistances(ctPtTmp,_maxDistance,tempField,hexOffsetArray[indexHex],hexDistanceArray[indexHex],hexNeighborOrderIndexArray[indexHex]);
00407
00408 }
00409
00410
00411 ctPtTmp=ctPt;
00412 indexHex=Y_ODD|Z_EVEN;
00413 if(dim.z > 1){
00414 if( !(ctPtTmp.y % 2) ){
00415 ctPtTmp.y+=1;
00416 }
00417 if( ctPtTmp.z % 2 )
00418 ctPtTmp.z+=1;
00419
00420 getOffsetsAndDistances(ctPtTmp,_maxDistance,tempField,hexOffsetArray[indexHex],hexDistanceArray[indexHex],hexNeighborOrderIndexArray[indexHex]);
00421
00422 }else{
00423 cerr<<"ctPtTmp.y % 2 ="<<ctPtTmp.y % 2 << " !ctPtTmp.y % 2="<<!(ctPtTmp.y % 2)<<endl;
00424 if( !(ctPtTmp.y % 2) ){
00425 ctPtTmp.y+=1;
00426 }
00427 cerr<<"odd even ctPtTmp="<<ctPtTmp<<endl;
00428 getOffsetsAndDistances(ctPtTmp,_maxDistance,tempField,hexOffsetArray[indexHex],hexDistanceArray[indexHex],hexNeighborOrderIndexArray[indexHex]);
00429
00430 }
00431
00432
00433 ctPtTmp=ctPt;
00434 indexHex=Y_ODD|Z_ODD;
00435 if(dim.z > 1){
00436 if( !(ctPtTmp.y % 2) ){
00437 ctPtTmp.y+=1;
00438 }
00439 if( !(ctPtTmp.z % 2) )
00440 ctPtTmp.z+=1;
00441
00442 getOffsetsAndDistances(ctPtTmp,_maxDistance,tempField,hexOffsetArray[indexHex],hexDistanceArray[indexHex],hexNeighborOrderIndexArray[indexHex]);
00443
00444 }else{
00445
00446 }
00447
00448
00449 ctPtTmp=ctPt;
00450 indexHex=Y_EVEN|Z_ODD;
00451 if(dim.z > 1){
00452 if( ctPtTmp.y % 2 ){
00453 ctPtTmp.y+=1;
00454 }
00455 if( !(ctPtTmp.z % 2) )
00456 ctPtTmp.z+=1;
00457
00458 getOffsetsAndDistances(ctPtTmp,_maxDistance,tempField,hexOffsetArray[indexHex],hexDistanceArray[indexHex],hexNeighborOrderIndexArray[indexHex]);
00459
00460 }else{
00461
00462 }
00463
00464
00465
00466
00467 indexHex=0;
00468
00469 for (indexHex=0 ; indexHex<maxHexArraySize; ++indexHex){
00470 cerr<<"INDEX HEX="<<indexHex<<endl;
00471 for( int i = 0 ; i < hexOffsetArray[indexHex].size() ; ++i){
00472 cerr<<" This is offset["<<i<<"]="<<hexOffsetArray[indexHex][i]<<" distance="<<hexDistanceArray[indexHex][i]<<endl;
00473 }
00474 }
00475
00476 Neighbor n;
00477 Point3D testPt(10,10,0);
00478 unsigned int idx=3;
00479 n=getNeighborDirect(testPt,idx );
00480 cerr<<"Neighbor="<<n<<endl;
00481 testPt = Point3D(10,11,0);
00482 n=getNeighborDirect(testPt,idx );
00483 cerr<<"Neighbor="<<n<<endl;
00484 testPt = Point3D(11,11,0);
00485 n=getNeighborDirect(testPt,idx );
00486 cerr<<"Neighbor="<<n<<endl;
00487
00488 cerr<<"\n\n\n ****************************Checking Bondary "<<endl;
00489
00490 testPt = Point3D(0,0,0);
00491 cerr<<"HexCoord(testPt)="<<HexCoord(testPt)<<endl;
00492 for (int i =0 ;i<6 ; ++i){
00493 n=getNeighborDirect(testPt,i );
00494 if(n.distance>0){
00495 cerr<<"Neighbor="<<n<<endl;
00496 }else{
00497 cerr<<"************************Not a neighbor= "<<n<<endl;
00498 }
00499 }
00500
00501 cerr<<"\n\n\n *****************Checkup Boundary"<<endl;
00502
00503 testPt = Point3D(0,dim.y-1,0);
00504 cerr<<"HexCoord(testPt)="<<HexCoord(testPt)<<endl;
00505 for (int i =0 ;i<6 ; ++i){
00506 n=getNeighborDirect(testPt,i );
00507 if(n.distance>0){
00508 cerr<<"Neighbor="<<n<<endl;
00509 }else{
00510 cerr<<"*****************Not a neighbor= "<<n<<endl;
00511 }
00512 }
00513
00514
00515 for (int i =1 ; i<=11 ; ++i){
00516 unsigned int maxIdx=getMaxNeighborIndexFromNeighborOrder(i);
00517 cerr<<"NEIGHBOR ORDER ="<<i<<" maxIdx="<<maxIdx<<endl;
00518
00519 }
00520
00521
00522
00523
00524
00525
00526
00527 }
00528
00529
00530 void BoundaryStrategy::getOffsetsAndDistances(
00531 Point3D ctPt,
00532 float maxDistance,
00533 Field3DImpl<char> & tempField,
00534 vector<Point3D> & offsetVecTmp,
00535 vector<float> &distanceVecTmp,
00536 vector<unsigned int> &neighborOrderIndexVecTmp
00537 )
00538 {
00539
00540 Point3D n;
00541
00542 unsigned int token = 0;
00543 double distance = 0;
00544 Coordinates3D<double> ctPtTrans, nTrans;
00545 Point3D offset;
00546 double distanceTrans=0.0;
00547
00548 offsetVecTmp.clear();
00549 distanceVecTmp.clear();
00550 neighborOrderIndexVecTmp.clear();
00551
00552 if (latticeType==HEXAGONAL_LATTICE){
00553 ctPtTrans=HexCoord(ctPt);
00554 }else{
00555 ctPtTrans=Coordinates3D<double>(ctPt.x,ctPt.y,ctPt.z);
00556 }
00557
00558
00559 while (true) {
00560 n = tempField.getNeighbor(ctPt, token, distance, false);
00561 if (distance > maxDistance*2.0) break;
00562
00563
00564
00565
00566 offset=n-ctPt;
00567
00568 if (latticeType==HEXAGONAL_LATTICE){
00569
00570 ctPtTrans=HexCoord(ctPt);
00571 nTrans=HexCoord(n);
00572 distanceTrans=calculateDistance(ctPtTrans,nTrans);
00573
00574 }else{
00575 ctPtTrans=Coordinates3D<double>(ctPt.x,ctPt.y,ctPt.z);
00576 nTrans=Coordinates3D<double>(n.x,n.y,n.z);
00577 distanceTrans=distance;
00578 }
00579
00580 if ( !checkIfOffsetAlreadyStacked(offset,offsetVecTmp) && distanceTrans<maxDistance+0.1 ){
00581
00582 offsetVecTmp.push_back(offset);
00583 distanceVecTmp.push_back(distanceTrans);
00584 }
00585 }
00586
00587
00588
00589
00590 multimap<float,Point3D> sortingMap;
00591 for( int i = 0 ; i < offsetVecTmp.size() ; ++i){
00592 sortingMap.insert(make_pair(distanceVecTmp[i],offsetVecTmp[i]));
00593 }
00594
00595
00596
00597
00598 offsetVecTmp.clear();
00599 distanceVecTmp.clear();
00600
00601 for (multimap<float,Point3D>::iterator mitr = sortingMap.begin() ; mitr != sortingMap.end() ; ++mitr){
00602
00603 distanceVecTmp.push_back(mitr->first);
00604 offsetVecTmp.push_back(mitr->second);
00605 }
00606 cerr<<"distanceVecTmp.size()="<<distanceVecTmp.size()<<endl;
00607
00608
00609 float currentDistance=1.0;
00610
00611
00612 for( int i = 0 ; i < distanceVecTmp.size() ; ++i){
00613 if(currentDistance<distanceVecTmp[i]){
00614 neighborOrderIndexVecTmp.push_back(i-i);
00615 currentDistance=distanceVecTmp[i];
00616 }
00617 }
00618
00619
00620
00621 }
00622
00623 void BoundaryStrategy::prepareNeighborListsSquare(float _maxDistance){
00624
00625 char a='0';
00626 Field3DImpl<char> tempField(dim,a);
00627 int margin=2*fabs(_maxDistance)+1;
00628 Point3D ctPt(dim.x/2,dim.y/2,dim.z/2);
00629 getOffsetsAndDistances(ctPt,_maxDistance,tempField,offsetVec,distanceVec,neighborOrderIndexVec);
00630
00631
00632 for( int i = 0 ; i < offsetVec.size() ; ++i){
00633 cerr<<" This is offset["<<i<<"]="<<offsetVec[i]<<" distance="<<distanceVec[i]<<endl;
00634 }
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657 }
00658
00659
00660
00661 void BoundaryStrategy::prepareNeighborLists(float _maxDistance){
00662 maxDistance=_maxDistance;
00663 cerr<<"generateLatticeMultiplicativeFactors"<<endl;
00664 lmf=generateLatticeMultiplicativeFactors(latticeType,dim);
00665 cerr<<"generateLatticeMultiplicativeFactors 1"<<endl;
00666 if(latticeType==HEXAGONAL_LATTICE){
00667 cerr<<"generateLatticeMultiplicativeFactors 2"<<endl;
00668 prepareNeighborListsHex(_maxDistance);
00669 cerr<<"generateLatticeMultiplicativeFactors 3"<<endl;
00670
00671 }else{
00672 prepareNeighborListsSquare(_maxDistance);
00673 }
00674
00675
00676
00677
00678 return ;
00679
00680
00681 }
00682
00683 unsigned int BoundaryStrategy::getMaxNeighborOrder(){
00684
00685
00686 unsigned int maxNeighborOrder=1;
00687 unsigned int previousMaxIdx=0;
00688 unsigned int currentMaxIdx=0;
00689
00690
00691 while(true){
00692 currentMaxIdx=getMaxNeighborIndexFromNeighborOrder(maxNeighborOrder);
00693
00694 if(previousMaxIdx==currentMaxIdx)
00695 break;
00696
00697 previousMaxIdx=currentMaxIdx;
00698 ++maxNeighborOrder;
00699 }
00700
00701 return --maxNeighborOrder;
00702
00703 }
00704
00705 void BoundaryStrategy::prepareNeighborListsBasedOnNeighborOrder(unsigned int _neighborOrder){
00706
00707 unsigned int maxNeighborOrder=getMaxNeighborOrder();
00708 cerr<<"maxNeighborOrder="<<maxNeighborOrder<<endl;
00709
00710 while((maxNeighborOrder-4)<_neighborOrder){
00711 cerr<<"RECALCULATING NEIGHBOR LIST"<<endl;
00712 prepareNeighborLists(2.0*maxDistance);
00713 maxNeighborOrder=getMaxNeighborOrder();
00714 cerr<<"current maxNeighborOrder="<<maxNeighborOrder<<endl;
00715 }
00716
00717 }
00718
00719
00720
00724
00725
00726
00727
00728
00729
00730
00731
00732 unsigned int BoundaryStrategy::getMaxNeighborIndexFromNeighborOrder(unsigned int _neighborOrder){
00733
00734 unsigned int maxNeighborIndex=0;
00735 unsigned int orderCounter=1;
00736
00737 if(latticeType==HEXAGONAL_LATTICE){
00738 unsigned int indexHex=Y_EVEN|Z_EVEN;
00739 double currentDepth=hexDistanceArray[indexHex][0];
00740
00741
00742
00743
00744 for(int i = 0 ; i < hexDistanceArray[indexHex].size() ; ++i){
00745
00746 ++maxNeighborIndex;
00747 if(hexDistanceArray[indexHex][i]>(currentDepth+0.005)){
00748 currentDepth = hexDistanceArray[indexHex][i];
00749 ++orderCounter;
00750 if(orderCounter>_neighborOrder){
00751 maxNeighborIndex=i-1;
00752 return maxNeighborIndex;
00753 }
00754 }
00755 }
00756 return --maxNeighborIndex;
00757
00758 }
00759 else{
00760
00761 double currentDepth=distanceVec[0];
00762
00763 for(int i = 0 ; i < distanceVec.size() ; ++i){
00764 if(distanceVec[i]>(currentDepth+0.005)){
00765 currentDepth=distanceVec[i];
00766 ++orderCounter;
00767 if(orderCounter>_neighborOrder){
00768 maxNeighborIndex=i-1;
00769 return maxNeighborIndex;
00770 }
00771 }
00772 }
00773 return --maxNeighborIndex;
00774 }
00775 }
00776
00777
00778 unsigned int BoundaryStrategy::getMaxNeighborIndexFromDepth(float depth){
00779
00780
00781 unsigned int maxNeighborIndex=0;
00782
00783 if(latticeType==HEXAGONAL_LATTICE){
00784 unsigned int indexHex=Y_EVEN|Z_EVEN;
00785
00786 for(int i = 0 ; i < hexDistanceArray[indexHex].size() ;++i){
00787 maxNeighborIndex=i;
00788 if(hexDistanceArray[indexHex][i]>depth){
00789 maxNeighborIndex=i-1;
00790 break;
00791 }
00792 }
00793 return maxNeighborIndex;
00794
00795 }
00796 else{
00797
00798 for(int i = 0 ; i < distanceVec.size() ;++i){
00799 maxNeighborIndex=i;
00800 if(distanceVec[i]>depth){
00801 maxNeighborIndex=i-1;
00802 break;
00803 }
00804 }
00805 return maxNeighborIndex;
00806 }
00807 }
00808
00809
00810
00811 Neighbor BoundaryStrategy::getNeighborDirect(Point3D & pt,unsigned int idx, bool checkBounds,bool calculatePtTrans ) {
00812 Neighbor n;
00813
00814
00815 unsigned int indexHex;
00816
00817 if(latticeType==HEXAGONAL_LATTICE){
00818
00819 indexHex=((pt.z%2)<<1)|(pt.y%2);
00820
00821
00822 n.pt=pt+hexOffsetArray[indexHex][idx];
00823
00824 }else{
00825 n.pt=pt+offsetVec[idx];
00826 }
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836 if(!checkBounds || isValid(n.pt)) {
00837
00838
00839 n.ptTrans=calculatePointCoordinates(n.pt);
00840 if(latticeType==HEXAGONAL_LATTICE){
00841 n.distance=hexDistanceArray[indexHex][idx];
00842 if (calculatePtTrans)
00843 n.ptTrans=HexCoord(n.pt);
00844
00845 }else{
00846 n.distance= distanceVec[idx]*lmf.lengthMF;
00847 if(calculatePtTrans)
00848 n.ptTrans=Coordinates3D<double>(pt.x,pt.y,pt.z);
00849 }
00850
00851 return n;
00852
00853 } else {
00854
00855 if (regular) {
00856 bool x_bool;
00857 bool y_bool;
00858 bool z_bool;
00859 int x=n.pt.x;
00860 int y=n.pt.y;
00861 int z=n.pt.z;
00862
00863
00864 x_bool = (isValid(x,dim.x) ? true : strategy_x->applyCondition(x, dim.x));
00865 y_bool = (isValid(y,dim.y) ? true : strategy_y->applyCondition(y, dim.y));
00866 z_bool = (isValid(z,dim.z) ? true : strategy_z->applyCondition(z, dim.z));
00867
00868
00869
00870 if(x_bool && y_bool && z_bool) {
00871 n.pt.x=x;
00872 n.pt.y=y;
00873 n.pt.z=z;
00874 n.ptTrans=calculatePointCoordinates(n.pt);
00875 if(latticeType==HEXAGONAL_LATTICE){
00876 n.distance=hexDistanceArray[indexHex][idx];
00877
00878 }else{
00879 n.distance= distanceVec[idx]*lmf.lengthMF;
00880
00881 }
00882 return n;
00883
00884 }else{
00885
00886 n.distance=0.0;
00887 return n;
00888 }
00889
00890 }
00891
00892 }
00893
00894
00895 }
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931