C:/Projekte/C++/FlowVIS_107/src/FlowGeometry.cpp

Go to the documentation of this file.
00001 
00002 // needed for writing log-file
00003 #include <iostream>
00004 #include <fstream>
00005 
00006 #include "FlowGeometry.h"
00007 #include "FlowChannel.h"
00008 #include "FlowData.h"
00009 #include "reverseBytes.h"
00010 
00011 using namespace std;
00012 
00013 
00014 
00015 FlowGeometry::FlowGeometry()
00016 {
00017   geometryData     = NULL;
00018   normGeometryData = NULL;
00019 }
00020 
00021 
00022 FlowGeometry::~FlowGeometry()
00023 {
00024   if ( geometryData )
00025     delete[] geometryData;
00026 
00027   if ( normGeometryData )
00028     delete[] normGeometryData;
00029 }
00030 
00031 
00032 bool FlowGeometry::readFromFile(char* header, FILE* fp, bool bigEndian)
00033 {
00034   isFlipped = false;
00035 
00036   std::cout << "\n\n ------- Loading grid ------- " << std::endl;
00037 
00038   //determine the dimensions
00039   sscanf( header, "SN4DB %d %d %d", &dim[0], &dim[1], &dim[2] );
00040   std::cout << "Dimensions: " << dim[0] << " x " << dim[1] << " x " << dim[2] << std::endl;
00041 
00042   if ( dim[2]!=1 )
00043   {
00044     std::cerr << "Invalid Z dimension value." << std::endl;
00045     return false;
00046   }
00047 
00048   // create space for grid-data
00049   geometryData = new vec3[ dim[0] * dim[1] ];
00050 
00051   //read the data in one chunk
00052   int result = (int) fread( geometryData, sizeof(vec3), dim[0] * dim[1], fp );
00053 
00054   // check if everything went fine
00055   if ( result != dim[0]*dim[1] )
00056   {
00057     std::cerr << "+ Error reading grid file." << std::endl << std::endl;
00058     return false;
00059   }
00060 
00061   // we usually do not have big endian
00062   if ( bigEndian )
00063     for (int j = 0; j < getDimX()*getDimY(); j++)
00064       for (int k = 0; k < 3; k++)
00065         geometryData[j][k] = reverseBytes<float>(geometryData[j][k]);
00066 
00067 
00068   // determine boundaries
00069   boundaryMin = vec3( getPos( 0 ) );                  //first vertex
00070   boundaryMax = vec3( getPos( (dim[0]*dim[1]) - 1) ); //last vertex
00071   boundarySize = boundaryMax - boundaryMin;           // size
00072 
00073   // print to screen
00074   std::cout << "X-Boundaries : " << boundaryMin[0]  << " .. " << boundaryMax[0]  << std::endl;
00075   std::cout << "Y-Boundaries : " << boundaryMin[1]  << " .. " << boundaryMax[1]  << std::endl;
00076   std::cout << "Boundary-Size: " << boundarySize[0] << " | "  << boundarySize[1] << std::endl;
00077 
00078 
00079   // check if axes are flipped
00080   // if X and Y are flipped, going in a row the y value increases and x stays the same
00081   // (block dataset is flipped)
00082   float maxYPos = getPosY( dim[0]-1 );
00083   float avgYPos = ( boundaryMin[1] + boundaryMax[1] ) * 0.5f;
00084 
00085   if ( avgYPos < maxYPos )
00086   //if ( avgYPos > maxYPos )
00087   //if (posy > average) // gv Shouldn't it be the other way 'round?
00088   {
00089     isFlipped = true;
00090     std::cout << "Flipped X and Y dimensions." << std::endl;
00091   }
00092   else isFlipped = false;
00093 
00094 
00095   // ( gv Do not change anything -> do this with OGL rotations !!! ) -> posssibly wrong -> flip axes now
00096 
00097   // gv Finally get rid of the problem with inverted, switched etc.. axes!!
00098   if ( isFlipped )
00099   {
00100     // switch axes NOW!
00101     // and in the remaining programm noone has to ever think about it again!
00102 
00103     vec3 temp;
00104 
00105     for ( int i=0; i<dim[0]*dim[1]; i++ )
00106     {
00107       temp = geometryData[ i ];
00108 
00109       geometryData[ i ].v[0] = temp.v[1];
00110       geometryData[ i ].v[1] = temp.v[0];
00111     }
00112 
00113     int dimTemp = dim[X];
00114     dim[X] = dim[Y];
00115     dim[Y] = dimTemp;
00116   } // if flipped
00117 
00118 
00119   // gv Move grid to origin
00120   if ( boundaryMin.v[0] != 0.0 || boundaryMin.v[1] != 0.0 )
00121     for( int i=0; i<dim[0]*dim[1]; i++ )
00122       geometryData[i] = geometryData[i] - boundaryMin;
00123 
00124 
00125   boundaryMax = boundaryMax - boundaryMin; // alternative: getPos( (dim[0]*dim[1]) - 1)
00126   boundaryMin = getPos( 0 ); // should always be zero now!
00127 
00128   // gv
00129   // Create space for normalized grid-points (so that we still have access to the original data)
00130   // do not invert y, since we do that with OGL rotations later
00131   normGeometryData = new vec3[ dim[0]*dim[1] ];
00132 
00133   for( int i=0; i<dim[0]*dim[1]; i++ )
00134     normGeometryData[i] = normalizeCoords( geometryData[i] );
00135 
00136 
00137 /* // gv Not sure if this is really such a good idea, since I think we just don't need it?!
00138 
00139   // nk Invert y of geometry data (convert from LHS to RHS) and normalize [0...1]
00140   for(int i = 0; i < getDimX() * getDimY(); i++)
00141   {
00142     vec3 pos = geometryData[i];
00143     pos = normalizeCoords(pos);
00144     pos[Y] = 1.0f - pos[Y];
00145     geometryData[i] = pos;
00146   }
00147 */
00148 
00149 /*
00150   //first vertex
00151   boundaryMin = vec3( getPos(0) );
00152 
00153   //last vertex
00154   boundaryMax = vec3( getPos( (dim[0]*dim[1]) - 1) );
00155 
00156   // size
00157   boundarySize = boundaryMax - boundaryMin;
00158 */
00159 
00160   // print new boundaries
00161   std::cout << "New X Boundaries: " << boundaryMin[0] << " .. " << boundaryMax[0] << std::endl;
00162   std::cout << "New Y Boundaries: " << boundaryMin[1] << " .. " << boundaryMax[1] << std::endl;
00163 
00164   // gv TEST: print coords of grid-points
00165   //printGridPoints();
00166 
00167   std::cout << " ------- Done loading grid ------- " << std::endl;
00168 
00169   // all done (hopefully)
00170   return true;
00171 }
00172 
00173 
00174 bool FlowGeometry::getIsFlipped()
00175 {
00176   return isFlipped;
00177 }
00178 
00179 
00180 
00181 /* gv Obsolete?
00183 int FlowGeometry::getXYvtx(vec3 pos)
00184 {
00185   int i;
00186   int j;
00187   //search for the column left to the vertex
00188   for (i = 0; (i < dim[0])&&(getPosX(getVtx(i,0)) < pos[0]); i++);
00189   //search for the row under the vertex
00190   for (j = 0; (j < dim[1])&&(getPosY(getVtx(0,j)) < pos[1]); j++);
00191 
00192   //return the vertex ID of the found vertex
00193   return getVtx((i<dim[0]) ? i : dim[0]-1, (j<dim[1]) ? j : dim[1]-1);
00194 }
00195 */
00196 
00197 inline vec3 FlowGeometry::getPos(int vtxID)
00198 {
00199   return geometryData[vtxID];
00200 }
00201 
00202 inline float FlowGeometry::getPosX(int vtxID)
00203 {
00204   return geometryData[vtxID][0];
00205 }
00206 
00207 inline float FlowGeometry::getPosY(int vtxID)
00208 {
00209   return geometryData[vtxID][1];
00210 }
00211 
00212 
00213 vec3 FlowGeometry::getNormPos(int vtxID)
00214 {
00215   return normGeometryData[vtxID];
00216 }
00217 
00218 
00219 static int closest = 0;
00220 //static bool global = true;  // gv Maybe needed for global vs. local search
00221 
00222 
00224 int FlowGeometry::getNearestVtx(vec3 pos)
00225 {
00226   //take the norm to the first vertex
00227   float dist = pos.dist2(getPos(0));
00228   //mark the vertex 0 as the closest one
00229 
00230   //float newd;
00231   //Iterate through all vertices and search for the enarest one. I know, this is so inefficient, that you'll have to rewrite it :P
00232   //for (int i = 1; i < dim[0]*dim[1]; i++)
00233   //{
00234   //  newd = pos.dist2(getPos(i));
00235   //  if (newd < dist)
00236   //  {
00237   //    dist = newd;
00238   //    closest = i;
00239   //  }
00240   //}
00241   //printf("%f, %f, id: %d\n", pos.v[0], pos.v[1], closest);
00242   return closest++;
00243 }
00244 
00245 
00246 bool FlowGeometry::getInterpolationAt_old(vec3 pos, int* vtxID, float* coef)
00247 //bool FlowGeometry::getInterpolationAt_old(vec3 pos, int* vtxID, float* coef)
00248 {
00249   std::cout << "getInterpolationAt... (old)" << std::endl;
00250 
00251   //if we are outside of the dataset, return false
00252   //please note, that this test is valid only for rectangular datasets (block, hurricane), but not for tube
00253   if ((pos[0]<boundaryMin[0])||(pos[1]<boundaryMin[1])||(pos[0]>boundaryMax[0])||(pos[1]>boundaryMax[1]))
00254     return false;
00255 
00256   //example of a low-quality lookup with no interpolation
00257   vtxID[0] = getNearestVtx(pos); //finds the nearest vertex to the given position and returns it's value as the dominanting one
00258   vtxID[1] = 0;
00259   vtxID[2] = 0;
00260   vtxID[3] = 0;
00261   coef[0] = 1.0f;
00262   coef[1] = 0.0f;
00263   coef[2] = 0.0f;
00264   coef[3] = 0.0f;
00265   return true;
00266 }
00267 
00268 
00272 bool FlowGeometry::getInterpolationAt( vec3 pos, vec3* value, FlowData* data )
00273 {
00274   //std::cout << "getInterpolationAt... (gv)" << std::endl;
00275 
00276 
00277   // lookup position in grid
00278   int xGridIdx = binarySearch( pos.v[0], 0, dim[X]-1, 0 );
00279   int yGridIdx = binarySearch( pos.v[1], 0, dim[Y]-1, 1 );
00280 
00281   //std::cout << "x-index found for " << pos.v[0] << ": " << xGridIdx << std::endl;
00282   //std::cout << "y-index found for " << pos.v[1] << ": " << yGridIdx << std::endl;
00283 
00284   // return false if not in grid
00285   if ( xGridIdx == -1 || yGridIdx == -1 ) return false;
00286 
00287   // interpolate cell-points
00288   int cell[2] = { xGridIdx, yGridIdx };  // lower-left point (=index) of cell containing the searchpoint
00289   vec3 interpolatedValue[1]; 
00290   bool retCode = interpolate( pos, cell, data, interpolatedValue );
00291   //vec3 interpolatedValue = interpolate( pos, cell, data );
00292 
00293   //std::cout << "interpolated value: " << interpolatedValue[0] << std::endl;
00294   value[0] = interpolatedValue[0];
00295 
00296   // TEST: print coords of grid-points
00297   //printGridPoints();
00298 
00299   // everything ok
00300   //return true;
00301   return retCode;
00302 }
00303 
00304 
00305 bool FlowGeometry::interpolate( vec3 pos, int* cell, FlowData* data, vec3 *interpolatedValue )
00306 {
00307   // indices of the cellpoints (cp):
00308   //
00309   //  (0,1)    (1,1)
00310   //    |--------|
00311   //    |        |
00312   //    |--------|
00313   //  (0,0)    (1,0)
00314 
00315   // calculate cell-incides
00316   int idxCp00 = cell[X] + cell[Y] * dim[X];
00317   int idxCp10 = idxCp00 + 1;
00318   int idxCp01 = idxCp00 + dim[X];
00319   int idxCp11 = idxCp01 + 1;
00320 
00321   // lookup cell-positions
00322   vec3 cp00 = normGeometryData[ idxCp00 ];
00323   vec3 cp10 = normGeometryData[ idxCp10 ];
00324   vec3 cp01 = normGeometryData[ idxCp01 ];
00325   vec3 cp11 = normGeometryData[ idxCp11 ];
00326 /*
00327   vec3 cp00 = geometryData[ idxCp00 ];
00328   vec3 cp10 = geometryData[ idxCp10 ];
00329   vec3 cp01 = geometryData[ idxCp01 ];
00330   vec3 cp11 = geometryData[ idxCp11 ];
00331 */
00332   // the coefficients for the interpolation
00333   float coeff00 = 0.0f;
00334   float coeff10 = 0.0f;
00335   float coeff01 = 0.0f;
00336   float coeff11 = 0.0f;
00337 
00338   // we need to calcualte the coefficients from the grid
00339   // Then interpolate the VELOCITIY VALUES from this grid-points with theri coeff
00340 
00341   // vec3 interpolatedVelocityValue = velocity[cp00] * coeff00 + velocity[cp10] * coeff10 
00342   //                                + velocity[cp01] * coeff01 + velocity[cp11] * coeff11;
00343 
00344 
00345   // calculate the coeff 
00346   // with weighted-square-method
00347 
00348   // cp0   v   pos      w        cp1
00349   //  |---------|-----------------| 
00350 
00351   float vx = pos[X] - cp00[X];
00352   float wx = cp10[X] - pos[X];
00353 
00354   float vy = pos[Y] - cp00[Y];
00355   float wy = cp01[Y] - pos[Y];
00356 
00357   float maxX = cp10[X] - cp00[X];
00358   float maxY = cp01[Y] - cp00[Y];
00359 
00360   coeff00 = (wx * wy) / ( maxX * maxY );
00361   coeff10 = (vx * wy) / ( maxX * maxY );
00362   coeff01 = (wx * vy) / ( maxX * maxY );
00363   coeff11 = (vx * vy) / ( maxX * maxY );
00364 
00365 /*
00366   // TEST
00367   // test == pos if correct coeffcients
00368   vec3 test = cp00 * coeff00 + 
00369               cp10 * coeff10 + 
00370               cp01 * coeff01 + 
00371               cp11 * coeff11;
00372 */
00373 
00374   // calculate interpolated value
00375   FlowChannel* velX = data->getChannel( X );
00376   FlowChannel* velY = data->getChannel( Y );
00377   FlowChannel* velZ = data->getChannel( Z );
00378 /*
00379   int ti = 152 + 203 * dim[X];
00380   vec3 tv( velX->getValue( ti ), velY->getValue( ti ), velZ->getValue( ti ) );
00381   cout << "tv: " << tv << "\n";
00382 */
00383   // lookup velocity-values
00384   vec3 vel00( velX->getValue( idxCp00 ), velY->getValue( idxCp00 ), velZ->getValue( idxCp00 ) );
00385   vec3 vel10( velX->getValue( idxCp10 ), velY->getValue( idxCp10 ), velZ->getValue( idxCp10 ) );
00386   vec3 vel01( velX->getValue( idxCp01 ), velY->getValue( idxCp01 ), velZ->getValue( idxCp01 ) );
00387   vec3 vel11( velX->getValue( idxCp11 ), velY->getValue( idxCp11 ), velZ->getValue( idxCp11 ) );
00388 /*
00389   cout << "v00: " << vel00
00390        << "\nv10: " << vel10
00391        << "\nv01: " << vel01
00392        << "\nv11: " << vel11 << "\n";
00393 */
00394 
00395   if ( ((vel00[X] == 0) && (vel00[Y] == 0)) ||
00396        ((vel10[X] == 0) && (vel10[Y] == 0)) ||
00397        ((vel01[X] == 0) && (vel01[Y] == 0)) ||
00398        ((vel11[X] == 0) && (vel11[Y] == 0)) )
00399   {
00400     /*
00401     cout << "there is a null-vector !!! pos: " << pos << "\n";
00402     cout << "cp00: " << idxCp00
00403        << "\ncp10: " << idxCp10
00404        << "\ncp01: " << idxCp01
00405        << "\ncp11: " << idxCp11 << "\n";
00406     */
00407     return false;
00408   }
00409 
00410   /*vec3*/ interpolatedValue[0] = vel00 * coeff00 + 
00411                               vel10 * coeff10 + 
00412                               vel01 * coeff01 + 
00413                               vel11 * coeff11;
00414 
00415 
00416 /*
00417   // print values (for debug)
00418   std::cout << "\n\n --- Print interpolation info --- " << std::endl;
00419   std::cout << "Spos: " << pos << std::endl << std::endl;
00420   std::cout << "TEST: " << test << std::endl << std::endl;
00421 
00422   std::cout << "idxCp00: " << idxCp00 << std::endl;
00423   std::cout << "idxCp10: " << idxCp10 << std::endl;
00424   std::cout << "idxCp01: " << idxCp01 << std::endl;
00425   std::cout << "idxCp11: " << idxCp11 << std::endl << std::endl;
00426 
00427   std::cout << "grid [ cp00 ] : " << geometryData[ idxCp00 ] << std::endl;
00428   std::cout << "grid [ cp10 ] : " << geometryData[ idxCp10 ] << std::endl;
00429   std::cout << "grid [ cp01 ] : " << geometryData[ idxCp01 ] << std::endl;
00430   std::cout << "grid [ cp11 ] : " << geometryData[ idxCp11 ] << std::endl << std::endl;
00431 
00432   std::cout << "vx: " << vx << ", wx: " << wx << std::endl;
00433   std::cout << "vy: " << vy << ", wy: " << wy << std::endl << std::endl;
00434 
00435   std::cout << "vel00: " << vel00 << std::endl;
00436   std::cout << "vel10: " << vel10 << std::endl;
00437   std::cout << "vel01: " << vel01 << std::endl;
00438   std::cout << "vel11: " << vel11 << std::endl << std::endl;
00439 
00440   std::cout << "coeff00: " << coeff00 << std::endl;
00441   std::cout << "coeff10: " << coeff10 << std::endl;
00442   std::cout << "coeff01: " << coeff01 << std::endl;
00443   std::cout << "coeff11: " << coeff11 << std::endl << std::endl;
00444 
00445   std::cout << "iPol: " << interpolatedValue << std::endl << std::endl;
00446 */
00447 
00448   return true;
00449   //return interpolatedValue;
00450 }
00451 
00452 
00456 int FlowGeometry::binarySearch( float searchValue, int begin, int end, int dimension )
00457 {
00458   bool found    = false;
00459   int  leftEnd  = begin;
00460   int  rightEnd = end;
00461   int  mid      = 0;
00462   int  currentIndex = 0;
00463 
00464 
00465   while ( !found && leftEnd <= rightEnd )
00466   {
00467     float currentValue;
00468     mid = ( leftEnd + rightEnd ) / 2;
00469     currentIndex = mid;
00470 
00471     currentValue = getCurrentSearchValue( currentIndex, dimension );
00472 
00473     if ( currentValue == searchValue )
00474       // found value
00475       found = true;
00476     else
00477     {
00478 
00479       if ( currentValue < searchValue  )
00480       {
00481         // check if neighborhood + 1 < searchValue
00482         currentIndex = mid + 1;
00483         currentValue = getCurrentSearchValue( currentIndex, dimension );
00484 
00485         if ( currentValue > searchValue )
00486         {
00487           // found value
00488           found = true;
00489           --currentIndex; // we want the lower left corner of the cell
00490         }
00491       }
00492 
00493       else // if ( currentValue > searchValue )
00494       {
00495         // check if neighborhood - 1 < searchValue
00496         currentIndex = mid - 1;
00497         currentValue = getCurrentSearchValue( currentIndex, dimension );
00498 
00499         if ( currentValue < searchValue )
00500         {
00501           // found value
00502           found = true;
00503         }
00504       }
00505 
00506       if ( !found ) // not yet found
00507       {
00508         if ( searchValue < currentValue )
00509           // continue search in left half
00510           rightEnd = mid - 1;
00511         else
00512           // continue search in right half
00513           leftEnd = mid + 1;
00514       }
00515     }
00516   } // while
00517 
00518   if ( found )
00519     // return found index
00520     return currentIndex;
00521   else
00522     // not found
00523     return -1;
00524 }
00525 
00526 
00530 int FlowGeometry::binarySearch2( float searchValue, int begin, int end, int dimension )
00531 {
00532   bool found    = false;
00533   int  leftEnd  = begin;
00534   int  rightEnd = end;
00535   int  mid      = 0;
00536   int  currentIndex = 0;
00537 
00538   // Problem: What, if value is not in array? -> returns not found
00539   // But: We want that the next lower value is returned!
00540   // => adapt this to be correct!
00541   //
00542   // Idea: keep closest match + it's distance (really neccessary?)
00543   // Search as long as leftEnd < rightEnd
00544   // If leftEnd > rightEnd, we have gone too far
00545   // Then, do sequential search to maxDim, stop if currentLower < searchValue && currentBigger > searchValue
00546   // (should work, shouldn't it?)
00547   //
00548   // We than have the index of the lower-left corner of the grid-cell containing the given point
00549   // Return -1 immediately if searchVAlue out of boundaries!
00550 
00551 /*
00552   if ( dimension == X )
00553   {
00554     float minVal = geometryData[ leftEnd  ].v[0];
00555     float maxVal = geometryData[ rightEnd ].v[0];
00556 
00557     float dummy = 0.0f;
00558 
00559   }
00560 */
00561 
00562   while ( !found && leftEnd <= rightEnd )
00563   {
00564     float currentValue;
00565     mid = ( leftEnd + rightEnd ) / 2;
00566     currentIndex = mid;
00567 
00568     currentValue = getCurrentSearchValue( currentIndex, dimension );
00569 
00570     if ( currentValue == searchValue )
00571       // found value
00572       found = true;
00573     else
00574     {
00575       // check neighborhood + 1
00576       currentIndex = mid + 1;
00577       currentValue = getCurrentSearchValue( currentIndex, dimension );
00578 
00579       if ( currentValue == searchValue )
00580         // found value
00581         found = true;
00582       else
00583       {
00584         // check neighborhood - 1
00585         currentIndex = mid - 1;
00586         currentValue = getCurrentSearchValue( currentIndex, dimension );
00587 
00588         if ( currentValue == searchValue )
00589           // found value
00590           found = true;
00591 
00592         else {
00593           // not yet found
00594 
00595           if ( searchValue < currentValue )
00596             // continue search in left half
00597             rightEnd = mid - 1;
00598           else
00599             // continue search in right half
00600             leftEnd = mid + 1;
00601         }
00602       }
00603     }
00604   } // while
00605 
00606   if ( found )
00607     // return found index
00608     return currentIndex;
00609   else
00610     // not found
00611     return -1;
00612 }
00613 
00614 
00615 float FlowGeometry::getCurrentSearchValue( int index, int dimension )
00616 {
00617   float value;
00618 
00619   if ( index == -1 )
00620   {
00621     //std::cout << "! Error: index -1 in FlowGeometry.getCurrentSearchValue!" << std::endl;
00622     return 0.0f;
00623   }
00624 
00625   if ( dimension == X )
00626     value = normGeometryData[ index ].v[0];
00627   else // dimension == Y
00628     value = normGeometryData[ dim[X] * index ].v[1];
00629 /*
00630   if ( dimension == X )
00631     value = geometryData[ index ].v[0];
00632   else // dimension == Y
00633     value = geometryData[ dim[X] * index ].v[1];
00634 */
00635   return value;
00636 }
00637 
00638 
00639 void FlowGeometry::printGridPoints()
00640 {
00641   std::cout << "Writing grid-point-coords to log-file (this may take a while - please be patient!) ... ";
00642 
00643   ofstream gridLogFile;
00644 
00645   gridLogFile.open ("grid_points.log");
00646   gridLogFile << "Grid-Point-Positions with their corresponding indices in geometryData:\n\n";
00647 
00648 /*
00649   // all
00650   for ( int i=0; i<dim[X]*dim[Y]; i++ )
00651     gridLogFile << i << ": " << geometryData[ i ] << "\n";
00652 */
00653 
00654 
00655   // X-dim
00656   gridLogFile << "X:\n";
00657   for ( int i=0; i<dim[X]; i++ )
00658   {
00659     gridLogFile << i << ": " << normGeometryData[ i ].v[0] << "\n";
00660   }
00661 
00662   // Y-dim
00663   gridLogFile << "\n\nY:\n";
00664   for ( int i=0; i<dim[Y]; i++ )
00665   {
00666     gridLogFile << i << ": " << normGeometryData[ i * dim[X] ].v[1] << "\n";
00667   }
00668 
00669 
00670   gridLogFile.close();
00671 
00672   std::cout << " done. " << std::endl;
00673 }
00674 
00675 
00676 
00677 inline float FlowGeometry::getMinX()
00678 {
00679   return boundaryMin[0];
00680 }
00681 
00682 inline float FlowGeometry::getMaxX()
00683 {
00684   return boundaryMax[0];
00685 }
00686 
00687 inline float FlowGeometry::getMinY()
00688 {
00689   return boundaryMin[1];
00690 }
00691 
00692 inline float FlowGeometry::getMaxY()
00693 {
00694   return boundaryMax[1];
00695 }
00696 
00697 inline int FlowGeometry::getDimX()
00698 {
00699   return dim[0];
00700   //return (isFlipped) ? dim[1] : dim[0];
00701 }
00702 
00703 inline int FlowGeometry::getDimY()
00704 {
00705   return dim[1];
00706   //return (isFlipped) ? dim[0] : dim[1];
00707 }
00708 
00709 inline int FlowGeometry::getDimZ()
00710 {
00711   return dim[2];
00712 }
00713 
00714 /* gv Obsolete?
00715 int FlowGeometry::getVtx(int x, int y)
00716 {
00717   return ( y*dim[0] ) + x;
00718 
00719   //if we need to flip the rows and columns, we do it here
00720   //return (isFlipped)? (x*dim[1]) + y : (y*dim[0]) + x;
00721 }
00722 
00723 int FlowGeometry::getVtxX(int vtxID)
00724 {
00725   return vtxID % dim[0];
00726 
00727   //if we need to flip the rows and columns, we do it here
00728   //return (isFlipped)? vtxID / dim[1] : vtxID % dim[0];
00729 }
00730 
00731 int FlowGeometry::getVtxY(int vtxID)
00732 {
00733   return vtxID / dim[0];
00734 
00735   //if we need to flip the rows and columns, we do it here
00736   //return (isFlipped)? vtxID % dim[1] : vtxID / dim[0];
00737 }
00738 
00739 int FlowGeometry::getRightNeigh(int vtxID)
00740 {
00741   int x = getVtxX(vtxID);
00742   return (x+1 < dim[0]) ? getVtx(x+1,getVtxY(vtxID)) : -1;
00743 }
00744 
00745 int FlowGeometry::getTopNeigh(int vtxID)
00746 {
00747   //remember that the data is structured with (0,0) in the upper-left corner and (1,1) in the lower-right
00748   //that's why we are subtracting 1 to find the top neighbour
00749   int y = getVtxY(vtxID);
00750   return (y+1 < dim[1]) ? getVtx(getVtxX(vtxID), y-1) : -1;
00751 }
00752 
00753 int FlowGeometry::getLeftNeigh(int vtxID)
00754 {
00755   int x = getVtxX(vtxID);
00756   return (x > 1) ? getVtx(x-1,getVtxY(vtxID)) : -1;
00757 }
00758 
00759 int FlowGeometry::getBottomNeigh(int vtxID)
00760 {
00761   //remember that the data is structured with (0,0) in the upper-left corner and (1,1) in the lower-right
00762   int y = getVtxY(vtxID);
00763   return (y < 1) ? getVtx(getVtxX(vtxID), y+1) : -1;
00764 }
00765 */
00766 vec3 FlowGeometry::normalizeCoords(vec3 pos)
00767 {
00768   vec3 u(pos - boundaryMin);
00769   //scale each component according to the side length
00770   u[0] /= boundarySize[0];
00771   u[1] /= boundarySize[1];
00772 
00773   return u;
00774 }
00775 
00776 vec3 FlowGeometry::unNormalizeCoords(vec3 pos)
00777 {
00778   vec3 u(pos);
00779   //multiply each component according to the side length
00780   u[0] *= boundarySize[0];
00781   u[1] *= boundarySize[1];
00782 
00783   return u += boundaryMin;
00784 }

Generated on Mon Jan 21 14:50:12 2008 for VisLU by  doxygen 1.5.4