00001 #include "FlowGeometry.h"
00002 #include "reverseBytes.h"
00003
00004 bool FlowGeometry::readFromFile(char* header, FILE* fp, bool bigEndian)
00005 {
00006 isFlipped = false;
00007
00008 sscanf(header,"SN4DB %d %d %d",&dim[0],&dim[1],&dim[2]);
00009 std::cout << "Dimensions: " << dim[0] << " x " << dim[1] << " x " << dim[2] << std::endl;
00010 if (dim[2]!=1)
00011 {
00012 std::cerr << "Invalid Z dimension value." << std::endl;
00013 return false;
00014 }
00015
00016 geometryData = new vec3[dim[0]*dim[1]];
00017
00018 int result = fread(geometryData,sizeof(vec3),dim[0]*dim[1],fp);
00019 if (result != dim[0]*dim[1])
00020 {
00021 std::cerr << "+ Error reading grid file." << std::endl << std::endl;
00022 return false;
00023 }
00024
00025 if (bigEndian)
00026 for (int j = 0; j < getDimX()*getDimY(); j++)
00027 for (int k = 0; k < 3; k++)
00028 geometryData[j][k] = reverseBytes<float>(geometryData[j][k]);
00029
00030
00031 boundaryMin = vec3(getPos(0));
00032
00033 boundaryMax = vec3(getPos((dim[0]*dim[1]) - 1));
00034 boundarySize = boundaryMax - boundaryMin;
00035
00036
00037 if (getPosY(dim[0]-1)>(boundaryMin[1] + boundaryMax[1])*0.5)
00038 {
00039
00040 isFlipped = true;
00041 std::cout << "Flipped Y and X dimensions." << std::endl;
00042 }
00043 else isFlipped = false;
00044
00045 std::cout << "X Boundaries: " << boundaryMin[0] << " ... " << boundaryMax[0] << std::endl;
00046 std::cout << "Y Boundaries: " << boundaryMin[1] << " ... " << boundaryMax[1] << std::endl;
00047
00048 return true;
00049 }
00050
00051 FlowGeometry::FlowGeometry()
00052 {
00053 tempValid = false;
00054 geometryData = NULL;
00055 }
00056
00057 FlowGeometry::~FlowGeometry()
00058 {
00059 if (geometryData)
00060 delete[] geometryData;
00061 }
00062
00064 int FlowGeometry::getXYvtx(vec3 pos)
00065 {
00066 int i;
00067 int j;
00068
00069 for (i = 0; (i < dim[0])&&(getPosX(getVtx(i,0)) < pos[0]); i++);
00070
00071 for (j = 0; (j < dim[1])&&(getPosY(getVtx(0,j)) < pos[1]); j++);
00072
00073
00074 return getVtx((i<dim[0]) ? i : dim[0]-1, (j<dim[1]) ? j : dim[1]-1);
00075 }
00076
00077 inline vec3 FlowGeometry::getPos(int vtxID)
00078 {
00079 return geometryData[vtxID];
00080 }
00081
00082 inline float FlowGeometry::getPosX(int vtxID)
00083 {
00084 return geometryData[vtxID][0];
00085 }
00086
00087 inline float FlowGeometry::getPosY(int vtxID)
00088 {
00089 return geometryData[vtxID][1];
00090 }
00091
00092 int FlowGeometry::getLeftUpperVtx(vec3 pos, int top, int bottom, int left, int right)
00093 {
00094 int midpos[2] = {(int)floor((right+left)/2.0f),(int)floor((bottom+top)/2.0f)};
00095
00096
00097 if (midpos[0]==left && midpos[1]==top) return getVtx(midpos[0],midpos[1]);
00098
00099 if (getPos(getVtx(midpos[0],midpos[1]))[1] > pos[1]) {
00100 bottom = midpos[1];
00101 } else {
00102 top = midpos[1];
00103 }
00104 if (getPos(getVtx(midpos[0],midpos[1]))[0] > pos[0]) {
00105 right = midpos[0];
00106 } else {
00107 left = midpos[0];
00108 }
00109 return getLeftUpperVtx(pos, top, bottom, left, right);
00110 }
00111
00112 int FlowGeometry::getNearestVtx(vec3 pos)
00113 {
00114 float dist = abs(pos[0]-getPos(0)[0]);
00115
00116 int closestx = 0;
00117 float newd;
00118
00119 for (int i = 1; i < dim[0]; i++) {
00120 newd = abs(pos[0]-getPos(i)[0]);
00121 if (newd >= dist) break;
00122 dist = newd;
00123 closestx = i;
00124 }
00125
00126 dist = abs(pos[1]-getPos(0)[1]);
00127 int closesty = 0;
00128
00129 for (int i = 1; i < dim[1]; i++) {
00130 newd = abs(pos[1]-getPos(i*dim[0])[1]);
00131 if (newd >= dist) break;
00132 dist = newd;
00133 closesty = i;
00134 }
00135
00136 return closesty*dim[0]+closestx;
00137
00140
00142
00143
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156 }
00157
00158 bool FlowGeometry::getInterpolationAt(vec3 pos, int* vtxID, float* coef)
00159 {
00160
00161
00162 if ((pos[0]<boundaryMin[0])||(pos[1]<boundaryMin[1])||(pos[0]>boundaryMax[0])||(pos[1]>boundaryMax[1]))
00163 return false;
00164
00165 if (tempValid && tempPos == pos) {
00166 vtxID[0] = tempVtx[0];
00167 vtxID[1] = tempVtx[1];
00168 vtxID[2] = tempVtx[2];
00169 vtxID[3] = tempVtx[3];
00170 coef[0] = tempCoef[0];
00171 coef[1] = tempCoef[1];
00172 coef[2] = tempCoef[2];
00173 coef[3] = tempCoef[3];
00174 return true;
00175 }
00176
00177 tempVtx[0] = vtxID[0] = getLeftUpperVtx(pos, 0, getDimY(), 0, getDimX());
00178 tempVtx[1] = vtxID[1] = getRightNeigh(vtxID[0]);
00179 tempVtx[2] = vtxID[2] = getBottomNeigh(vtxID[0]);
00180 tempVtx[3] = vtxID[3] = getBottomNeigh(vtxID[1]);
00181
00182
00183 vec3 a = getPos(vtxID[0]);
00184 vec3 b = getPos(vtxID[1]);
00185 vec3 c = getPos(vtxID[2]);
00186 vec3 d = getPos(vtxID[3]);
00187
00188
00189 float dX = pos[0] - getPos(vtxID[0])[0];
00190 float dY = pos[1] - getPos(vtxID[0])[1];
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213 float gridDiffX = getPos(vtxID[1])[0]-getPos(vtxID[0])[0];
00214 float gridDiffY = getPos(vtxID[2])[1]-getPos(vtxID[0])[1];
00215
00216 float ratio[4];
00217 ratio[0] = (gridDiffX-dX)/gridDiffX;
00218 ratio[1] = dX/gridDiffX;
00219 ratio[2] = (gridDiffY-dY)/gridDiffY;
00220 ratio[3] = dY/gridDiffY;
00221 tempCoef[0] = coef[0] = ratio[0]*ratio[2];
00222 tempCoef[1] = coef[1] = ratio[1]*ratio[2];
00223 tempCoef[2] = coef[2] = ratio[0]*ratio[3];
00224 tempCoef[3] = coef[3] = ratio[1]*ratio[3];
00225
00226 tempPos = pos;
00227 tempValid = true;
00228
00229 return true;
00230 }
00231
00232 inline float FlowGeometry::getMinX()
00233 {
00234 return boundaryMin[0];
00235 }
00236
00237 inline float FlowGeometry::getMaxX()
00238 {
00239 return boundaryMax[0];
00240 }
00241
00242 inline float FlowGeometry::getMinY()
00243 {
00244 return boundaryMin[1];
00245 }
00246
00247 inline float FlowGeometry::getMaxY()
00248 {
00249 return boundaryMax[1];
00250 }
00251
00252 inline int FlowGeometry::getDimX()
00253 {
00254 return (isFlipped) ? dim[1] : dim[0];
00255 }
00256
00257 inline int FlowGeometry::getDimY()
00258 {
00259 return (isFlipped) ? dim[0] : dim[1];
00260 }
00261
00262 inline int FlowGeometry::getDimZ()
00263 {
00264 return dim[2];
00265 }
00266
00267 int FlowGeometry::getVtx(int x, int y)
00268 {
00269
00270 return (isFlipped)? (x*dim[1]) + y : (y*dim[0]) + x;
00271 }
00272
00273 int FlowGeometry::getVtxX(int vtxID)
00274 {
00275
00276 return (isFlipped)? vtxID / dim[1] : vtxID % dim[0];
00277 }
00278
00279 int FlowGeometry::getVtxY(int vtxID)
00280 {
00281
00282 return (isFlipped)? vtxID % dim[1] : vtxID / dim[0];
00283 }
00284
00285 int FlowGeometry::getRightNeigh(int vtxID)
00286 {
00287 int x = getVtxX(vtxID);
00288 return (x+1 < getDimX()) ? getVtx(x+1,getVtxY(vtxID)) : -1;
00289 }
00290
00291 int FlowGeometry::getTopNeigh(int vtxID)
00292 {
00293
00294
00295 int y = getVtxY(vtxID);
00296 return (y+1 < dim[1]) ? getVtx(getVtxX(vtxID), y-1) : -1;
00297 }
00298
00299 int FlowGeometry::getLeftNeigh(int vtxID)
00300 {
00301 int x = getVtxX(vtxID);
00302 return (x > 1) ? getVtx(x-1,getVtxY(vtxID)) : -1;
00303 }
00304
00305 int FlowGeometry::getBottomNeigh(int vtxID)
00306 {
00307
00308 int y = getVtxY(vtxID);
00309 return (y+1 < getDimY()) ? getVtx(getVtxX(vtxID), y+1) : -1;
00310 }
00311
00312 vec3 FlowGeometry::normalizeCoords(vec3 pos)
00313 {
00314 vec3 u(pos - boundaryMin);
00315
00316 u[0] /= boundarySize[0];
00317 u[1] /= boundarySize[1];
00318
00319 return u;
00320 }
00321
00322 vec3 FlowGeometry::unNormalizeCoords(vec3 pos)
00323 {
00324 vec3 u(pos);
00325
00326 u[0] *= boundarySize[0];
00327 u[1] *= boundarySize[1];
00328
00329 return u += boundaryMin;
00330 }