colormap_interpolant::colormap_interpolant(std::vector<std::pair<double, vec3>> xps) { std::sort(xps.begin(), xps.end(), [](auto a, auto b) { return a.first < b.first; }); std::vector<double> xs, yr, yg, yb; for (auto p : xps) { xs.push_back(p.first); yr.push_back(p.second[0]); yg.push_back(p.second[1]); yb.push_back(p.second[2]); } r = cubic_interp(0, 255, xs, yr); g = cubic_interp(0, 255, xs, yg); b = cubic_interp(0, 255, xs, yb); }
Var* ff_cinterp(vfuncptr func, Var* arg) { Var* v[3] = {NULL, NULL, NULL}; float ignore = FLT_MIN; char* type = NULL; Alist alist[6]; alist[0] = make_alist("object", ID_VAL, NULL, &v[0]); alist[1] = make_alist("from", ID_VAL, NULL, &v[1]); alist[2] = make_alist("to", ID_VAL, NULL, &v[2]); alist[3] = make_alist("type", ID_ENUM, NULL, type); alist[4] = make_alist("ignore", DV_FLOAT, NULL, &ignore); alist[5].name = NULL; if (parse_args(func, arg, alist) == 0) return (NULL); if (v[0] == NULL || v[1] == NULL || v[2] == NULL) { parse_error("error, usage: cinterp(y1,x1,x2)\n"); return (NULL); } if (V_DSIZE(v[0]) != V_DSIZE(v[1])) { parse_error("error: x1 and y1 must be the same size\n"); return (NULL); } return (cubic_interp(v[0], v[1], v[2], type, ignore)); }
void TestInterpolation<T>::testGetIndexBounds() { USING_NK_NS USING_NKHIVE_NS // construct volume T default_val(1); vec3d res(1.0); vec3d kernel_offset(0.5); typename Volume<T>::shared_ptr volume( new Volume<T>(1, 2, default_val, res, kernel_offset)); // create interpolator CubicInterpolation<T> cubic_interp(volume); // test interior point on a cell boundary vec3d voxel_coords(2.0,2.0,2.0); vec3i voxel_indices(2,2,2); vec3i min_indices, max_indices; cubic_interp.getIndexBounds(voxel_coords, voxel_indices, min_indices, max_indices); CPPUNIT_ASSERT(min_indices == vec3i(0,0,0)); CPPUNIT_ASSERT(max_indices == vec3i(3,3,3)); // test interior point voxel_coords = vec3d(2.15,2.2,2.1); voxel_indices = vec3i(2,2,2); cubic_interp.getIndexBounds(voxel_coords, voxel_indices, min_indices, max_indices); CPPUNIT_ASSERT(min_indices == vec3i(0,0,0)); CPPUNIT_ASSERT(max_indices == vec3i(3,3,3)); // test interior point rounded up voxel_coords = vec3d(2.75,2.8,2.9); voxel_indices = vec3i(2,2,2); cubic_interp.getIndexBounds(voxel_coords, voxel_indices, min_indices, max_indices); CPPUNIT_ASSERT(min_indices == vec3i(1,1,1)); CPPUNIT_ASSERT(max_indices == vec3i(4,4,4)); // test an arbitrary point voxel_coords = vec3d(1.9,1.2,3.2); voxel_indices = vec3i(1,1,3); cubic_interp.getIndexBounds(voxel_coords, voxel_indices, min_indices, max_indices); CPPUNIT_ASSERT(min_indices == vec3i(0,-1,1)); CPPUNIT_ASSERT(max_indices == vec3i(3,2,4)); }
double FuselageXSec::get_tan_str2( int index ) { int q2 = num_pnts/2; int q1 = q2/2; int q3 = q2 + q1; int q4 = num_pnts-1; double val = 0.0; if ( index <= q1 ) val = cubic_interp( 0, index, q1, topTanStr2(), rightTanStr2() ); else if ( index <= q2 ) val = cubic_interp( q1, index, q2, rightTanStr2(), botTanStr2() ); else if ( index <= q3 ) val = cubic_interp( q2, index, q3, botTanStr2(), leftTanStr2() ); else val = cubic_interp( q3, index, q4, leftTanStr2(), topTanStr2() ); return val; }
void TestInterpolation<T>::testCollectInterpolants() { USING_NK_NS USING_NKHIVE_NS // construct volume T default_val(1); vec3d res(1.0); vec3d kernel_offset(0.5); typename Volume<T>::shared_ptr volume( new Volume<T>(1, 2, default_val, res, kernel_offset)); // easy to track values i32 value=0; for (i32 z=0; z<4; ++z) { for (i32 y=0; y<4; ++y) { for (i32 x=0; x<4; ++x) { volume->set(x,y,z,value++); } } } vec3i min_indices(0,0,0); vec3i max_indices(3,3,3); CubicInterpolation<T> cubic_interp(volume); // test interior typename CubicInterpolation<T>::calc_type interpolants[64]; cubic_interp.collectInterpolants(min_indices, max_indices, interpolants); for (i32 i=0; i<64; ++i) { CPPUNIT_ASSERT(interpolants[i] == typename CubicInterpolation<T>::calc_type(i)); } // test boundary min_indices = vec3i(0,0,1); max_indices = vec3i(3,3,4); cubic_interp.collectInterpolants(min_indices, max_indices, interpolants); for (i32 i=0; i<48; ++i) { CPPUNIT_ASSERT(interpolants[i] == typename CubicInterpolation<T>::calc_type(i + 16)); } for (i32 i=0; i<16; ++i) { CPPUNIT_ASSERT(interpolants[i + 48] == typename CubicInterpolation<T>::calc_type(1)); } }
Var* ff_interp(vfuncptr func, Var* arg) { Var* v[3] = {NULL, NULL, NULL}; float ignore = FLT_MIN; const char* usage = "usage: %s(y1,x1,x2,[type={'linear'|'cubic'}]"; char* type = (char*)""; const char* types[] = {"linear", "cubic", NULL}; Var* out; Alist alist[9]; alist[0] = make_alist("object", ID_VAL, NULL, &v[0]); alist[1] = make_alist("from", ID_VAL, NULL, &v[1]); alist[2] = make_alist("to", ID_VAL, NULL, &v[2]); alist[3] = make_alist("ignore", DV_FLOAT, NULL, &ignore); alist[4] = make_alist("type", ID_ENUM, types, &type); alist[5] = make_alist("y1", ID_VAL, NULL, &v[0]); alist[6] = make_alist("x1", ID_VAL, NULL, &v[1]); alist[7] = make_alist("x2", ID_VAL, NULL, &v[2]); alist[8].name = NULL; if (parse_args(func, arg, alist) == 0) return (NULL); if (v[0] == NULL) { parse_error("%s: y1 not specified.", func->name); parse_error(usage, func->name); return (NULL); } if (v[1] == NULL) { parse_error("%s: x1 not specified.", func->name); parse_error(usage, func->name); return (NULL); } if (v[2] == NULL) { parse_error("%s: x2 not specified.", func->name); parse_error(usage, func->name); return (NULL); } if (V_DSIZE(v[0]) != V_DSIZE(v[1])) { parse_error("Object and From values must be same size\n"); } if (type == NULL || strlen(type) == 0 || !strcasecmp(type, "linear")) { out = linear_interp(v[0], v[1], v[2], ignore); } else if (!strncasecmp(type, "cubic", 5)) { out = cubic_interp(v[0], v[1], v[2], type, ignore); } else { parse_error("%s: Unrecognized type: %s\n", func->name, type); } return (out); }
void TestInterpolation<T>::testInterp() { USING_NK_NS USING_NKHIVE_NS // construct volume T default_val(1); vec3d res(1.0); vec3d kernel_offset(0.5); typename Volume<T>::shared_ptr volume( new Volume<T>(1, 2, default_val, res, kernel_offset)); // easy to track values i32 value=0; for (i32 z=0; z<4; ++z) { for (i32 y=0; y<4; ++y) { for (i32 x=0; x<4; ++x) { volume->set(x,y,z,value++); } } } // test an interior point typename CubicInterpolation<T>::calc_type coords[3]; coords[0] = 1.75; coords[1] = 2.0; coords[2] = 2.25; CubicInterpolation<T> cubic_interp(volume); T result; cubic_interp.interp(coords[0], coords[1], coords[2], result); CHECK_RESULT(35.25); // test boundary points coords[0] = 1.5; coords[1] = 1.5; coords[2] = 1.5; cubic_interp.interp(coords[0], coords[1], coords[2], result); CHECK_RESULT(21.0); coords[0] = 1.5; coords[1] = 1.5; coords[2] = 2.5; cubic_interp.interp(coords[0], coords[1], coords[2], result); CHECK_RESULT(37.0); coords[0] = 2.5; coords[1] = 1.5; coords[2] = 2.5; cubic_interp.interp(coords[0], coords[1], coords[2], result); CHECK_RESULT(38.0); coords[0] = 2.5; coords[1] = 2.5; coords[2] = 2.5; cubic_interp.interp(coords[0], coords[1], coords[2], result); CHECK_RESULT(42.0); }