shape_t* shape_copy(const shape_t* source) { assert(source != NULL); shape_t* shape = shape_new(); kv_copy(point_t, shape->points, source->points); kv_copy(point_t, shape->hull , source->hull ); kv_copy(poly_t , shape->polys , source->polys ); return shape; }
mesh_t* mesh_create(int x, int y) { shape_t* s = shape_new(); loop_t l; kv_init(l); uint32_t steps = 50; for(uint32_t i=0; i<steps; i++) { double dr = 150.0 * cos(2*3.1415926*i/steps*5); point_t p = (point_t) { x/2.0 + (200-dr) * cos(dr/250.0 + 2.0*3.1415926*i/steps), y/2.0 + (200-dr) * sin(dr/250.0 + 2.0*3.1415926*i/steps)}; uint32_t pid = shape_add_point(s, p); kv_push(uint32_t, l, pid); } kv_push(loop_t, s->loops, l); return shape_triangulate(s); }
int main() { const double Lx = 8; const double Ly = 4; const double Lz = 1; const int Nx = 32*4*4*2; const int Ny = 16*4*4*2; const int Nz = 8*4*4*2; const double dx = Lx/Nx; const double dy = Ly/Ny; const double dz = Lz/Nz; const double tau_tail = 1.52; const double a0 = 1.29, a1 = -22.57, a2 = 78.39, a3 = -52.83; const double t = 0.0; const double time_period = 1.0; double interp_coefs[4]; interp_coefs[0] = a0; interp_coefs[1] = a1; interp_coefs[2] = a2; interp_coefs[3] = a3; //No. of points on the backbone and till head. const int headNs = int(ceil(LENGTH_TILLHEAD/dx)); const int tailNs = int(ceil((LENGTH_FISH - LENGTH_TILLHEAD)/dx) ); const int bodyNs = headNs + tailNs + 1; std::vector<std::pair<int,int> > immersedBodyData(bodyNs); std::vector<std::pair<double,double> > immersedBodyWidthHeight(bodyNs); for (int i = 1; i <= headNs + 1; ++i) { const double s = (i-1)*dx; const double section = sqrt(2*WIDTH_HEAD*s - s*s); const double height = MINOR_AXIS*std::sqrt( 1 - pow((s - MAJOR_AXIS)/MAJOR_AXIS,2) ); const int numPtsInSection = int( ceil(section/dy) ); const int numPtsInHeight = int( ceil(height/dz) ); immersedBodyData[i-1] = std::make_pair(numPtsInSection,numPtsInHeight); immersedBodyWidthHeight[i-1] = std::make_pair(section,height); } for (int i = headNs + 2; i <= bodyNs; ++i) { const double s = (i-1)*dx; const double section = WIDTH_HEAD*(LENGTH_FISH - s)/(LENGTH_FISH - LENGTH_TILLHEAD); const double height = MINOR_AXIS*std::sqrt( 1 - pow((s - MAJOR_AXIS)/MAJOR_AXIS,2) ); const int numPtsInSection = int( ceil(section/dy) ); const int numPtsInHeight = int( ceil(height/dz) ); immersedBodyData[i-1] = std::make_pair(numPtsInSection,numPtsInHeight); immersedBodyWidthHeight[i-1] = std::make_pair(section,height); } int total_lag_pts = 0; double input[7]; input[0] = interp_coefs[0]; input[1] = interp_coefs[1]; input[2] = interp_coefs[2]; input[3] = interp_coefs[3]; input[4] = tau_tail; input[5] = t; input[6] = time_period; gsl_function Fx, Fy; Fx.function = xPosition; Fx.params = input; Fy.function = yPosition; Fy.params = input; double ybase, xbase, errory, errorx; size_t nevalsy, nevalsx; //Find the deformed shape. Rotate the shape about center of mass. std::vector<std::vector<double> > shape_new(3); for (int i = 1; i <= bodyNs; ++i) { const int numPtsInSection = immersedBodyData[i-1].first; const int numPtsInHeight = immersedBodyData[i-1].second; const double width = immersedBodyWidthHeight[i-1].first; const double depth = immersedBodyWidthHeight[i-1].second; const double s = (i-1)*dx; gsl_integration_qng(&Fx,0,s,1e-8,0.0,&xbase,&errorx,&nevalsx); gsl_integration_qng(&Fy,0,s,1e-8,0.0,&ybase,&errory,&nevalsy); if (numPtsInSection && numPtsInHeight) { //Fill the middle line first. for (int k = -numPtsInHeight; k <= numPtsInHeight; ++k) { shape_new[0].push_back(xbase); shape_new[1].push_back(ybase); shape_new[2].push_back(k*dz); }//middle line filled. total_lag_pts += 2*numPtsInHeight + 1; //Fill the rest of the cross section next. for (int j = 1; j <= numPtsInSection; ++j) { const double y = j*dy; for (int k = -numPtsInHeight; k <= numPtsInHeight; ++k) { const double z = k*dz; if ( (std::pow(y/width,2) + std::pow(z/depth,2)) <= 1 ) //use elliptical cross sections { shape_new[0].push_back(xbase); //right side. shape_new[1].push_back(ybase + y); shape_new[2].push_back(z); shape_new[0].push_back(xbase); //left side. shape_new[1].push_back(ybase - y); shape_new[2].push_back(z); total_lag_pts += 2; } } }//cross section filled } } std::fstream eelstream; eelstream.open("eel3d.vertex",std::fstream::out); assert((unsigned)total_lag_pts == shape_new[0].size()); eelstream << total_lag_pts << "\n"; for (int k = 1; k <= total_lag_pts ; ++k) eelstream << shape_new[0][k-1] + 5.5 << "\t" << shape_new[1][k-1] << "\t" << shape_new[2][k-1] << "\n"; return 0; }
shapes_v* shapes_load_shp(const char* filename) { shapes_v* shapes = shapes_new(); double adfMinBound[4], adfMaxBound[4]; // Read file SHPHandle hSHP = SHPOpen( filename, "rb" ); assert(hSHP != NULL); // Print shape bounds int shapes_count, shapes_vype; SHPGetInfo( hSHP, &shapes_count, &shapes_vype, adfMinBound, adfMaxBound ); // printf( "Shapefile Type: %s # of Shapes: %d\n\n", // SHPTypeName( shapes_vype ), shapes_count ); // printf( "File Bounds: (%.15g,%.15g,%.15g,%.15g)\n" // " to (%.15g,%.15g,%.15g,%.15g)\n", // adfMinBound[0], adfMinBound[1], // adfMinBound[2], adfMinBound[3], // adfMaxBound[0], adfMaxBound[1], // adfMaxBound[2], adfMaxBound[3]); // Iterate through shapes for(int i = 0; i < shapes_count; i++ ) { shape_t* shape = shape_new(); SHPObject *shp = SHPReadObject(hSHP, i); assert(shp != NULL); if(shp->nParts == 0) continue; // first part starts at point 0 assert(shp->panPartStart[0] == 0); // add points for(uint32_t j=0; j< shp->nVertices; j++) { point_t p = (point_t){shp->padfX[j], shp->padfY[j]}; shape_add_point(shape, p); } uint32_t parts = shp->nParts; for (uint32_t j=0; j<parts; j++) { uint32_t s = shp->panPartStart[j]; uint32_t e = (j+1 < parts) ? shp->panPartStart[j+1]: shp->nVertices; poly_t p = (poly_t){s, e-s}; shape_add_poly(shape, p); } shape->bbox = (bbox_t) { (point_t){shp->dfXMin, shp->dfYMin}, (point_t){shp->dfXMax, shp->dfYMax} }; shapes_add_shape(shapes, shape); SHPDestroyObject( shp ); } SHPClose( hSHP ); return shapes; }