00001
00002
00003
00004
00006
00007 #include "TObjArray.h"
00008 #include "TMath.h"
00009
00010
00011
00012
00013
00014
00015 #include "BField/TIntList.h"
00016
00017
00018
00019
00020 #include "BField/BFLWingedEdge.h"
00021 #include "BField/BFLVorOperator.h"
00022 #include "BField/BFLInterpolation.h"
00023 #include "BField/BFLCache.h"
00024 #include "BField/BFLAnsysLookup.h"
00025 #include "BField/BfldLoanPool.h"
00026 #include "BField/BfldMeshVoronoi.h"
00027 #include "Conventions/Munits.h"
00028 #include "MessageService/MsgService.h"
00029
00030 #include <fstream>
00031
00032 CVSID("$Id: BFLInterpolation.cxx,v 1.12 2005/02/03 22:35:49 rhatcher Exp $");
00033
00034 ClassImp(BFLInterpolation)
00035
00036 class BfldHandyMath {
00037 public:
00038 BfldHandyMath(void) {
00039 }
00040
00041 static double Det(double a11,double a12,double a13,
00042 double a21,double a22,double a23,
00043 double a31,double a32,double a33) {
00044 return a11 * a22 * a33 - a11 * a23 * a32 - a12 * a21 * a33
00045 + a12 * a23 * a31 + a13 * a21 * a32 - a13 * a22 * a31;
00046 }
00047
00048 static double Det(const TVector3 &v1,const TVector3 &v2,
00049 const TVector3 &v3) {
00050 return Det(v1.X(),v1.Y(),v1.Z(),
00051 v2.X(),v2.Y(),v2.Z(),
00052 v3.X(),v3.Y(),v3.Z());
00053 }
00054
00055
00056
00057
00058 static bool IsCCW(const TVector3 &v1,const TVector3 &v2,
00059 const TVector3 &v3) {
00060 return (v2.X() - v1.X()) * (v3.Y() - v1.Y())
00061 - (v2.Y() - v1.Y()) * (v3.X() - v1.X()) > 0;
00062 }
00063
00064
00065
00066
00067
00068 static bool IsInWedge(const TVector3 &v,const TVector3 &v1,
00069 const TVector3 &v2,const TVector3 &v3) {
00070 bool flag1 = IsCCW(v2,v1,v3),
00071 flag2 = IsCCW(v2,v1,v),
00072 flag3 = IsCCW(v1,v3,v);
00073 return ((flag1 && flag2 && flag3) || (!flag1 && !flag2 && !flag3));
00074 }
00075
00076 static bool IsInTri(const TVector3 &v,const TVector3 &v1,
00077 const TVector3 &v2,const TVector3 &v3) {
00078 bool flag1 = IsCCW(v2,v1,v3),
00079 flag2 = IsCCW(v2,v1,v),
00080 flag3 = IsCCW(v1,v3,v),
00081 flag4 = IsCCW(v2,v,v3);
00082 return ((flag1 && flag2 && flag3 && flag4)
00083 || (!flag1 && !flag2 && !flag3 && !flag4));
00084
00085 }
00086 };
00087
00088 ofstream *gBfldtestFile;
00089
00090 BFLInterpolation::BFLInterpolation(TObjArray * bfield,
00091 BFLWingedEdge * voronoi)
00092 {
00093 fBField = bfield;
00094 fVor = voronoi;
00095 fOp = new BFLVorOperator(voronoi);
00096 fNPolygs = fVor->GetNofPolygons() - 3;
00097
00098 fCache = new BFLCache();
00099 SetInterpolant(BfldInterpMethod::kClosest);
00100
00101 fPolygons = new TIntList();
00102 fVertices = new TObjArray(20);
00103
00104 fSearchSeed = 1;
00105
00106 gBfldtestFile = new ofstream("BfldPlanarInterpErrs.err",ios::app);
00107 }
00109
00110 BFLInterpolation::~BFLInterpolation()
00111 {
00112 fPolygons->Delete();
00113 delete fPolygons; fPolygons=0;
00114 fVertices->Delete();
00115 delete fVertices; fVertices=0;
00116 delete fOp; fOp=0;
00117 delete fVor; fVor=0;
00118 fBField->Delete();
00119 delete fBField; fBField=0;
00120 delete fCache; fCache=0;
00121
00122 delete gBfldtestFile;
00123 }
00125
00126 TVector3 BFLInterpolation::GetB(const TVector3& PosVector,
00127 const Bool_t updateSeedPolygon)
00128 {
00129 Int_t istatus;
00130 TVector3 BF(0.,0.,0.);
00131 BFLNode point(PosVector.X(),PosVector.Y());
00132
00133 switch(fHowToInterpolate) {
00134 case(BfldInterpMethod::kNatural):
00135 istatus = FormVoronoiCell(&point);
00136 if(istatus == kFail) {
00137 BF = CNInterpolation(&point);
00138 } else {
00139 BF = NNInterpolation(&point);
00140 ResetForNextQuery();
00141 }
00142 break;
00143 case(BfldInterpMethod::kClosest):
00144 BF = CNInterpolation(&point);
00145 break;
00146 case(BfldInterpMethod::kBilinear):
00147 BF = BilinearInterpolation(&point);
00148 break;
00149 case(BfldInterpMethod::kPlanar):
00150 BF = PlanarInterpolation(&point);
00151 break;
00152 default:
00153 MSG("BFL",Msg::kWarning)
00154 << "You did not specified a valid interpolation method" << endl;
00155 }
00156
00157 if (updateSeedPolygon) SetSearchSeed(GetLastPolygon());
00158 return BF;
00159 }
00161
00162 Int_t BFLInterpolation::FormVoronoiCell(BFLNode * point)
00163 {
00164 Int_t EdgeID, StartEdgeID, LastEdgeID, iedge, ivtx = 0;
00165
00166
00167 fOp->SetCurrentGen(point);
00168 fCurrentPolygID = fOp->FindCurrentPolygon(fSearchSeed);
00169
00170 fOp->SetCurrentPolygID(fCurrentPolygID);
00171 fPolygons->Add(fCurrentPolygID);
00172
00173 EdgeID = fOp->GetFirstIntersectEdge();
00174 if(EdgeID == -1) return kFail;
00175
00176 StartEdgeID = EdgeID;
00177 LastEdgeID = 0;
00178
00179 do {
00180
00181
00182
00183
00184
00185 fVertices->Add(new BFLNode(fOp->FindNewVtx(EdgeID)));
00186
00187
00188 iedge = fOp->GetNextIntersectEdge(EdgeID);
00189 if (iedge == LastEdgeID ) {
00190
00191
00192
00193 fCurrentPolygID = fOp->MoveToNextPolygon(fCurrentPolygID,EdgeID);
00194 fOp->SetCurrentPolygID(fCurrentPolygID);
00195 fPolygons->Add(fCurrentPolygID);
00196
00197 LastEdgeID = EdgeID;
00198 EdgeID = fOp->GetNextIntersectEdge(EdgeID);
00199
00200 } else {
00201 LastEdgeID = EdgeID;
00202 EdgeID = iedge;
00203 }
00204
00205 ivtx++;
00206 if(ivtx > kMaxVtx) return kFail;
00207
00208 } while(EdgeID != StartEdgeID);
00209
00210
00211 fVertices->Add(new BFLNode(fOp->FindNewVtx(EdgeID)));
00212
00213 return 0;
00214 }
00216
00217 TVector3 BFLInterpolation::NNInterpolation(BFLNode * point)
00218 {
00219 Int_t NatNeighbor = 0, ID = 0;
00220 Double_t AreaSum = 0, NeighborArea = 0, bx = 0, by = 0;
00221
00222
00223 Double_t TotalArea = CellArea(fVertices);
00224
00225
00226 for(Int_t inn=0; inn<fPolygons->NumberOfElements()-1; inn++) {
00227 NatNeighbor = fPolygons->At(inn);
00228
00229
00230
00231 TObjArray * Area = new TObjArray(55);
00232 BFLNode * FirstVtx = (BFLNode *) fVertices->At(inn);
00233 BFLNode * SecondVtx = (BFLNode *) fVertices->At(inn+1);
00234
00235 if (!FirstVtx || !SecondVtx) {
00236
00237 MSG("BFL",Msg::kWarning)
00238 << "failed fVertices->At(inn) " << inn
00239 << " FirstVtx " << FirstVtx << " SecondVtx " << SecondVtx
00240 << endl
00241 << " fPolygons->NumberOfElements "
00242 << fPolygons->NumberOfElements() << endl;
00243 break;
00244 }
00245
00246 Int_t Clockwiseness = fOp->Clockwise(FirstVtx,SecondVtx,point);
00247
00248
00249 TIntList * VtxAroundNeighbor = fOp->RetrieveVtxSurrPolygon(NatNeighbor);
00250
00251 Int_t ivtxslot=0;
00252 for(Int_t ivtx=0; ivtx<VtxAroundNeighbor->NumberOfElements(); ivtx++) {
00253 Int_t VtxID = VtxAroundNeighbor->At(ivtx);
00254 BFLNode * Vtx = fVor->GetVtx(VtxID);
00255
00256 if(fOp->Clockwise(FirstVtx,SecondVtx,Vtx) == Clockwiseness) {
00257 Area->AddAt(Vtx,ivtxslot);
00258 ivtxslot++;
00259 } else {
00260
00261
00262 delete Vtx;
00263 }
00264 }
00265
00266 VtxAroundNeighbor->Delete();
00267 delete VtxAroundNeighbor; VtxAroundNeighbor=0;
00268
00269
00270 if(ivtxslot == 0) {
00271 MSG("BFL",Msg::kWarning)
00272 << "BFLInterpolation::NNInterpolation --- subcell not formed"
00273 << endl
00274 << " BFLNode 'point' " << point->GetNodeID()
00275 << " x= " << point->GetX() << " y= " << point->GetY() << endl;
00276 return CNInterpolation(point);
00277 }
00278
00279
00280
00281
00282 BFLNode * FirstVtxCopy = new BFLNode(*FirstVtx);
00283 BFLNode * SecondVtxCopy = new BFLNode(*SecondVtx);
00284
00285 if(ivtxslot == 1) {
00286 Area->AddAt(FirstVtxCopy,1);
00287 Area->AddAt(SecondVtxCopy,2);
00288 } else {
00289 Int_t vcw = fOp->Clockwise((BFLNode *)Area->At(0),
00290 (BFLNode *)Area->At(1),FirstVtx);
00291
00292 if(fOp->Clockwise((BFLNode *)Area->At(1),FirstVtx,SecondVtx) == vcw) {
00293 Area->AddAt(FirstVtxCopy,ivtxslot);
00294 Area->AddAt(SecondVtxCopy,ivtxslot+1);
00295 } else {
00296 Area->AddAt(SecondVtxCopy,ivtxslot);
00297 Area->AddAt(FirstVtxCopy,ivtxslot+1);
00298 }
00299 }
00300
00301 NeighborArea = CellArea(Area);
00302 AreaSum += NeighborArea;
00303
00304 ID = fVor->GetGeneratorID(NatNeighbor);
00305 if (ID<0) {
00306
00307 MSG("BFL",Msg::kWarning)
00308 << "BFLInterpolation::NNInterpolation bad ID: " << ID << endl;
00309 } else {
00310 bx += NeighborArea * ((TVector2 *) fBField->At(ID))->X();
00311 by += NeighborArea * ((TVector2 *) fBField->At(ID))->Y();
00312 }
00313
00314
00315 Area->Delete();
00316 delete Area; Area=0;
00317 }
00318
00319
00320 NatNeighbor = fPolygons->At(fPolygons->NumberOfElements() - 1);
00321 NeighborArea = TotalArea - AreaSum;
00322
00323 ID = fVor->GetGeneratorID(NatNeighbor);
00324
00325 if (ID<0) {
00326
00327 MSG("BFL",Msg::kWarning)
00328 << "BFLInterpolation::NNInterpolation bad ID: " << ID << endl;
00329 } else {
00330 bx += NeighborArea * ((TVector2 *) fBField->At(ID))->X();
00331 by += NeighborArea * ((TVector2 *) fBField->At(ID))->Y();
00332 }
00333
00334 bx /= TotalArea;
00335 by /= TotalArea;
00336
00337 fOp->ResetVtxCache();
00338
00339 return TVector3(bx,by,0);
00340 }
00342
00343 TVector3 BFLInterpolation::CNInterpolation(BFLNode * point)
00344 {
00345 fOp->SetCurrentGen(point);
00346 fCurrentPolygID = fOp->FindCurrentPolygon(fSearchSeed);
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365 if(fCurrentPolygID > 3) {
00366 Int_t ID = fVor->GetGeneratorID(fCurrentPolygID);
00367 return *(TVector3 *) fBField->At(ID);
00368 } else return TVector3(0,0,0);
00369 }
00371
00372 void BFLInterpolation::ResetForNextQuery(void)
00373 {
00374 fVertices->Delete();
00375 fPolygons->Delete();
00376 }
00378
00379 Double_t BFLInterpolation::CellArea(TObjArray * vertices)
00380 {
00381
00382
00383 Double_t AreaOfCell = 0;
00384 BFLNode * Vtx;
00385
00386 TMatrix area = TMatrix(3,3);
00387 for(Int_t i=0; i<3; i++) area(i,2)=1;
00388
00389 area(0,0) = ((BFLNode *) vertices->At(0))->GetX();
00390 area(0,1) = ((BFLNode *) vertices->At(0))->GetY();
00391
00392 Int_t ivtx=0;
00393 TIter nextv(vertices);
00394 while( (Vtx = (BFLNode *)nextv()) ) {
00395 if(ivtx == 1) {
00396 area(1,0) = Vtx->GetX();
00397 area(1,1) = Vtx->GetY();
00398 }
00399 if(ivtx == 2) {
00400 area(2,0) = Vtx->GetX();
00401 area(2,1) = Vtx->GetY();
00402 AreaOfCell += 0.5 * area.Determinant();
00403 ivtx = 1;
00404 area(1,0) = area(2,0);
00405 area(1,1) = area(2,1);
00406 }
00407 ivtx++;
00408 }
00409
00410 return TMath::Abs(AreaOfCell);
00411 }
00413
00414 TVector3 BFLInterpolation::BilinearInterpolation(BFLNode * point)
00415 {
00416
00417 fOp->SetCurrentGen(point);
00418 fCurrentPolygID = fOp->FindCurrentPolygon(fSearchSeed);
00419
00420
00421 BfldLoanPool * loanpool = BfldLoanPool::Instance();
00422
00423 Int_t NodeID = ((BfldMeshVoronoi*)(loanpool->GetMesh(fGrid,0)))
00424 ->FindANSYSGenerator(fCurrentPolygID);
00425
00426
00427 BFLAnsysLookup lookup = fVor->GetAnsysLookupTable();
00428
00429
00430
00431 TObjArray cells;
00432 lookup.FindNode(NodeID,&cells);
00433
00434
00435 TIter nextentry(&cells);
00436 BFLNode2ACell * TableEntry = 0, * SelectedTableEntry = 0;
00437 while( (TableEntry = (BFLNode2ACell*) nextentry() ) ) {
00438
00439 Bool_t IsInside = IsInsideANSYSCell(TableEntry,point);
00440 if(IsInside) SelectedTableEntry = (BFLNode2ACell *) (TableEntry->Clone());
00441 if(IsInside) break;
00442 }
00443
00444
00445
00446 Int_t nodes[kNMaxNodesPerACell];
00447 SelectedTableEntry->GetCellNodes(nodes);
00448
00449
00450
00451
00452
00453 delete SelectedTableEntry;
00454
00455 return TVector3(0,0,0);
00456 }
00457
00459
00460 TVector3 BFLInterpolation::PlanarInterpolation(BFLNode *rNode) {
00461
00462 fOp->SetCurrentGen(rNode);
00463 fCurrentPolygID = fOp->FindCurrentPolygon(fSearchSeed);
00464
00465 if(fCurrentPolygID <= 3) {
00466
00467
00468 return TVector3(0,0,0);
00469 }
00470
00471
00472 TVector3 r(rNode->GetX(),rNode->GetY(),0);
00473
00474
00475 TVector3 r1(fVor->GetGeneratorX(fVor->PolygonToGenerator(fCurrentPolygID)),
00476 fVor->GetGeneratorY(fVor->PolygonToGenerator(fCurrentPolygID)),
00477 0);
00478
00479
00480
00481
00482
00483
00484
00485 int genID = fVor->GetGeneratorID(fCurrentPolygID);
00486 TVector3 b1 = *(TVector3 *)(fBField->At(genID));
00487
00488 const double kDistanceThresholdSquared = 10.0;
00489
00490 if((r1-r).Mag2() < kDistanceThresholdSquared) {
00491
00492
00493
00494
00495 return b1;
00496 }
00497
00498
00499
00500
00501 TIntList *edgesList = fOp->RetrieveEdgesSurrPolygon(fCurrentPolygID);
00502
00503 TVector3 r2,r3;
00504 int polyID,edgeID,gen2ID,gen3ID=-1;
00505 int i;
00506
00507
00508
00509
00510
00511
00512 int n = edgesList->NumberOfElements();
00513 bool isFound = false;
00514
00515 edgeID = edgesList->At(0);
00516 polyID = fVor->GetLeftPolyg(edgeID);
00517 if(polyID == fCurrentPolygID) {
00518 polyID = fVor->GetRightPolyg(edgeID);
00519 }
00520
00521
00522
00523
00524
00525 gen2ID = fVor->PolygonToGenerator(polyID);
00526 r2.SetXYZ(fVor->GetGeneratorX(gen2ID),fVor->GetGeneratorY(gen2ID),0);
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541 for(i = 1;i <= n;++i) {
00542 edgeID = edgesList->At(i % n);
00543 polyID = fVor->GetLeftPolyg(edgeID);
00544
00545
00546
00547 if(polyID == fCurrentPolygID)
00548 polyID = fVor->GetRightPolyg(edgeID);
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562 gen3ID = fVor->PolygonToGenerator(polyID);
00563
00564
00565 r3.SetXYZ(fVor->GetGeneratorX(gen3ID),fVor->GetGeneratorY(gen3ID),0);
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576 if(BfldHandyMath::IsInWedge(r,r1,r2,r3)) {
00577 if(isFound) {
00578 MSG("Bfldtest",Msg::kDebug)
00579 << "r seems to be in several wedges!" << endl;
00580 }
00581 else {
00582 isFound = true;
00583 break;
00584 }
00585 }
00586
00587 r2 = r3;
00588 gen2ID = gen3ID;
00589 }
00590
00591 if(!isFound) {
00592
00593 MSG("Bfldtest",Msg::kWarning)
00594 << "Couldn't pick a wedge for r = (" << r.X() << ","
00595 << r.Y() << ")!" << endl;
00596 return b1;
00597 }
00598
00599
00600
00601
00602
00603
00604
00605 if(!BfldHandyMath::IsInTri(r,r1,r2,r3)) {
00606
00607
00608
00609
00610
00611
00612 int homePolyID = fVor->GeneratorToPolygon(gen3ID);
00613 edgesList
00614 = fOp->RetrieveEdgesSurrPolygon(homePolyID);
00615 n = edgesList->NumberOfElements();
00616
00617
00618 isFound = false;
00619 for(i = 0;i < n;++i) {
00620 if(edgesList->At(i) == edgeID) {
00621 isFound = true;
00622 break;
00623 }
00624 }
00625 if(!isFound) {
00626 MSG("Bfldtest",Msg::kWarning)
00627 << "Couldn't find g1-g3 edge for secondary search." << endl;
00628 return b1;
00629 }
00630
00631 int index = i - 1;
00632 if(index < 0)
00633 index += n;
00634
00635 int direction = -1;
00636
00637
00638
00639
00640
00641 edgeID = edgesList->At(index);
00642 if(fVor->GeneratorToPolygon(gen2ID) != fVor->GetLeftPolyg(edgeID)
00643 && fVor->GeneratorToPolygon(gen2ID) != fVor->GetRightPolyg(edgeID))
00644 direction = 1;
00645
00646 index = i + 2 * direction;
00647 if(index < 0)
00648 index += n;
00649 if(index >= n)
00650 index -= n;
00651
00652 edgeID = edgesList->At(index);
00653 polyID = fVor->GetLeftPolyg(edgeID);
00654 if(polyID == fVor->GeneratorToPolygon(gen3ID))
00655 polyID = fVor->GetRightPolyg(edgeID);
00656
00657 r1.SetX(fVor->GetGeneratorX(fVor->PolygonToGenerator(polyID)));
00658 r1.SetY(fVor->GetGeneratorY(fVor->PolygonToGenerator(polyID)));
00659
00660 genID = fVor->GetGeneratorID(polyID);
00661 if(genID == -1)
00662 b1.SetXYZ(0,0,0);
00663 else
00664 b1 = *(TVector3 *)(fBField->At(genID));
00665 }
00666
00667
00668
00669
00670 if(!BfldHandyMath::IsInTri(r,r1,r2,r3)) {
00671 MSG("Bfldtest",Msg::kWarning)
00672 << "Couldn't pick out Delaunay triangle for r = (" << r.X() << ","
00673 << r.Y() << ")!" << endl;
00674
00675 (*gBfldtestFile) << r.X() << " " << r.Y() << endl;
00676
00677
00678 return CNInterpolation(rNode);
00679 }
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695 TVector3 b2;
00696 TVector3 b3;
00697
00698
00699
00700
00701 if(fVor->GeneratorToPolygon(gen2ID) <= 3)
00702 b2.SetXYZ(0,0,0);
00703 else
00704 b2 = *(TVector3 *)(fBField->At(fVor->GetGeneratorID(gen2ID)));
00705
00706 if(fVor->GeneratorToPolygon(gen3ID) <= 3)
00707 b3.SetXYZ(0,0,0);
00708 else
00709 b3 = *(TVector3 *)(fBField->At(fVor->GetGeneratorID(gen3ID)));
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721 TVector3 b(0,0,0);
00722
00723
00724
00725
00726
00727 double invDet = 1.0 / BfldHandyMath::Det(r1.X(),r1.Y(),1,
00728 r2.X(),r2.Y(),1,
00729 r3.X(),r3.Y(),1);
00730 TVector3 mInv1(r2.Y() - r3.Y(),r3.Y() - r1.Y(),r1.Y() - r2.Y());
00731 mInv1 *= invDet;
00732 TVector3 mInv2(r3.X() - r2.X(),r1.X() - r3.X(),r2.X() - r1.X());
00733 mInv2 *= invDet;
00734 TVector3 mInv3(r2.X() * r3.Y() - r3.X() * r2.Y(),
00735 r3.X() * r1.Y() - r3.Y() * r1.X(),
00736 r1.X() * r2.Y() - r1.Y() * r2.X());
00737 mInv3 *= invDet;
00738
00739
00740
00741 TVector3 bVals(b1.X(),b2.X(),b3.X());
00742 TVector3 coeffs(mInv1.Dot(bVals),mInv2.Dot(bVals),mInv3.Dot(bVals));
00743 b.SetX(r.X() * coeffs.X() + r.Y() * coeffs.Y() + coeffs.Z());
00744
00745 bVals.SetXYZ(b1.Y(),b2.Y(),b3.Y());
00746 coeffs.SetXYZ(mInv1.Dot(bVals),mInv2.Dot(bVals),mInv3.Dot(bVals));
00747 b.SetY(r.X() * coeffs.X() + r.Y() * coeffs.Y() + coeffs.Z());
00748
00749 return b;
00750 }
00751
00753
00754 void BFLInterpolation::IntBI1stOrder(void)
00755 {
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815 MSG("BFL",Msg::kFatal)
00816 << "IntBI1stOrder is a completely void method" << endl;
00817 }
00818
00820
00821 Bool_t BFLInterpolation::IsInsideANSYSCell(BFLNode2ACell * TableEntry,
00822 BFLNode * point)
00823 {
00824
00825
00826
00827
00828
00829
00830 Bool_t first = kTRUE;
00831 Bool_t IsInside = kTRUE;
00832 Int_t clockwiseness = 1;
00833 BfldMeshVoronoi * mesh;
00834 BFLVorOperator vorop;
00835 Int_t nodes[kNMaxNodesPerACell];
00836
00837 BfldLoanPool * loanpool = BfldLoanPool::Instance();
00838
00839 mesh = ((BfldMeshVoronoi*)(loanpool->GetMesh(fGrid,0)));
00840
00841 TableEntry->GetCellNodes(nodes);
00842
00843 for(Int_t inode = 0; inode <kNMaxNodesPerACell; inode++) {
00844
00845 Int_t nodeIdA = nodes[inode];
00846 Int_t nodeIdB = (inode+1 == kNMaxNodesPerACell) ? nodes[0] : nodes[inode+1];
00847
00848 BFLNode nA( (mesh->GetGeneratorPosition(nodeIdA)).X(),
00849 (mesh->GetGeneratorPosition(nodeIdA)).Y() );
00850
00851 BFLNode nB( (mesh->GetGeneratorPosition(nodeIdB)).X(),
00852 (mesh->GetGeneratorPosition(nodeIdB)).Y() );
00853
00854 Int_t icw = vorop.Clockwise(&nA,&nB,point);
00855
00856 if(first) {
00857 clockwiseness = icw;
00858 first = kFALSE;
00859 } else {
00860 if (icw != clockwiseness) IsInside = kFALSE;
00861 }
00862
00863 }
00864
00865 return IsInside;
00866 }