bool Grid::nextRayCell(Vec3u& current_cell, Vec3u& next_cell) { next_cell = current_cell; real t_min, t; unsigned i; t_min = FLT_MAX; // init tmin with handle of the case where one or 2 _u[i] = 0. unsigned coord = 0; // predominant coord(0=x, 1=y, 2=z) // using a parametric equation of // a line : B = A + t u, we find // the tx, ty and tz respectively coresponding // to the intersections with the plans: // x = _cell_size[0], y = _cell_size[1], z = _cell_size[2] for (i = 0; i < 3; i++) { if (_ray_dir[i] == 0) continue; if (_ray_dir[i] > 0) t = (_cell_size[i] - _pt[i]) / _ray_dir[i]; else t = -_pt[i] / _ray_dir[i]; if (t < t_min) { t_min = t; coord = i; } } // We use the parametric line equation and // the found t (tamx) to compute the // B coordinates: Vec3r pt_tmp(_pt); _pt = pt_tmp + t_min * _ray_dir; // We express B coordinates in the next cell // coordinates system. We just have to // set the coordinate coord of B to 0 // of _CellSize[coord] depending on the sign // of _u[coord] if (_ray_dir[coord] > 0) { next_cell[coord]++; _pt[coord] -= _cell_size[coord]; // if we are out of the grid, we must stop if (next_cell[coord] >= _cells_nb[coord]) return false; } else { int tmp = next_cell[coord] - 1; _pt[coord] = _cell_size[coord]; if (tmp < 0) return false; next_cell[coord]--; } _t += t_min; if (_t >= _t_end) return false; return true; }
void ChebyshevFitterTest::testFit() { ims::ChebyshevFitter fitter2(2); std::vector<double> a; std::vector<double> b; /* test identity transformation */ a.push_back(-31.7); b.push_back(-31.7); a.push_back(0.0); b.push_back(0.0); a.push_back(2.0); b.push_back(2.0); a.push_back(17.0); b.push_back(17.0); a.push_back(22.0); b.push_back(22.0); a.push_back(500.0); b.push_back(500.0); a.push_back(2000.0); b.push_back(2000.0); a.push_back(3000.0); b.push_back(3000.0); std::auto_ptr<ims::PolynomialTransformation> pt1 = fitter2.fit(a.begin(), a.end(), b.begin(), b.end()); std::vector<double>::const_iterator cit; for (cit = a.begin(); cit != a.end(); ++cit) { // TODO: it seems that CPPUNIT_ASSERT_DOUBLES_EQUAL does not fail if one of the doubles is NaN CPPUNIT_ASSERT_DOUBLES_EQUAL( *cit, pt1->transform(*cit), 1.0e-10 ); } /* test a different transformation */ // create a transformation ims::PolynomialTransformation pt_tmp(5); pt_tmp.setCoefficient(0, 3.7); pt_tmp.setCoefficient(1, 2.529); pt_tmp.setCoefficient(2, -19.3); pt_tmp.setCoefficient(3, 1409.7); pt_tmp.setCoefficient(4, 13.62); pt_tmp.setCoefficient(5, -7.0); // transform a to b using pt_tmp b.clear(); //std::vector<double>::iterator it; for (cit = a.begin(); cit != a.end(); ++cit) { b.push_back(pt_tmp.transform(*cit)); } // estimate 5th degree polynomial ims::ChebyshevFitter fitter5(5); std::auto_ptr<ims::PolynomialTransformation> pt2 = fitter5.fit(a.begin(), a.end(), b.begin(), b.end()); // ... and compare to original for (size_t i = 0; i <= 5; ++i) { CPPUNIT_ASSERT( !isnan(pt2->getCoefficient(i)) ); // leave 1.0e-5 in here, 1.0e-8 is too strict CPPUNIT_ASSERT_DOUBLES_EQUAL( pt_tmp.getCoefficient(i), pt2->getCoefficient(i), 1.0e-5 ); } }
/*! Method which enables to compute a NURBS curve passing through a set of data points. The result of the method is composed by a knot vector, a set of control points and a set of associated weights. \param l_crossingPoints : The list of data points which have to be interpolated. */ void vpNurbs::globalCurveInterp(const std::list<vpMeSite> &l_crossingPoints) { std::vector<vpImagePoint> v_crossingPoints; vpMeSite s = l_crossingPoints.front(); vpImagePoint pt(s.ifloat,s.jfloat); vpImagePoint pt_1 = pt; v_crossingPoints.push_back(pt); std::list<vpMeSite>::const_iterator it = l_crossingPoints.begin(); ++it; for(; it!=l_crossingPoints.end(); ++it){ vpImagePoint pt_tmp(it->ifloat, it->jfloat); if (vpImagePoint::distance(pt_1, pt_tmp) >= 10){ v_crossingPoints.push_back(pt_tmp); pt_1 = pt_tmp; } } globalCurveInterp(v_crossingPoints, p, knots, controlPoints, weights); }