catmull_rom returning a single point

Hi all, I am trying to interpolate some data with a *catmull_rom* spline available in boost math (interpolation). However, the resulting spline collapses to a single point for all /s/, corresponding to the first control point, /points_intr[0]/. Below, the c++ code segment of the interpolation is depicted: std::vector<std::array<double, 2>> points_intr(16); points_intr[0] = { 1.263270, 0.774614 }; points_intr[1] = { 1.876, 2.480 }; points_intr[2] = { 1.651110, 4.550 }; points_intr[3] = { 1.426340, 5.688 }; points_intr[4] = { 1.429, 7.054 }; points_intr[5] = { 2.073220, 8.377020 }; points_intr[6] = { 3.910, 9.140 }; points_intr[7] = { 6.430, 9.537 }; points_intr[8] = { 8.950, 9.859 }; points_intr[9] = { 11.470, 10.317 }; points_intr[10] = { 12.730, 10.6456 }; points_intr[11] = { 13.990, 11.0741 }; points_intr[12] = { 15.335, 11.6928 }; points_intr[13] = { 16.680, 12.5661 }; points_intr[14] = { 18.3538, 14.830 }; points_intr[15] = { 18.700, 16.056 }; boost::math::catmull_rom<std::array<double, 2>> interpolator_cr(std::move(points_intr)); auto max_s = interpolator_cr.max_parameter(); std::array<double, 2> inter_points; for (int i = 0; i < 100; i++) { inter_points = interpolator_cr(max_s * (i / num_points)); geometry_msgs::Point p; p.x = inter_points[0]; p.y = inter_points[1]; p.z = z; //p.z = inter_points[2]; marker.points.push_back(p); DEBUG_INFO("spline %d: (x, y) %f, %f, current_s: %f", i, p.x, p.y, max_s * (i / 100.0)); } I'm using boost 1.71.0 -- Sent from: http://boost.2283326.n4.nabble.com/Boost-Users-f2553780.html

Hi there, You will need to normalise (0 - 1) your data set first. To interpolate, you will need to pass normalised values, as well. Then you can unscale the output in the range you want. On Mon, Sep 30, 2019 at 1:51 AM hgrwilson via Boost-users < boost-users@lists.boost.org> wrote:
Hi all,
I am trying to interpolate some data with a *catmull_rom* spline available in boost math (interpolation). However, the resulting spline collapses to a single point for all /s/, corresponding to the first control point, /points_intr[0]/.
Below, the c++ code segment of the interpolation is depicted:
std::vector<std::array<double, 2>> points_intr(16);
points_intr[0] = { 1.263270, 0.774614 }; points_intr[1] = { 1.876, 2.480 }; points_intr[2] = { 1.651110, 4.550 }; points_intr[3] = { 1.426340, 5.688 }; points_intr[4] = { 1.429, 7.054 }; points_intr[5] = { 2.073220, 8.377020 }; points_intr[6] = { 3.910, 9.140 }; points_intr[7] = { 6.430, 9.537 }; points_intr[8] = { 8.950, 9.859 }; points_intr[9] = { 11.470, 10.317 }; points_intr[10] = { 12.730, 10.6456 }; points_intr[11] = { 13.990, 11.0741 }; points_intr[12] = { 15.335, 11.6928 }; points_intr[13] = { 16.680, 12.5661 }; points_intr[14] = { 18.3538, 14.830 }; points_intr[15] = { 18.700, 16.056 };
boost::math::catmull_rom<std::array<double, 2>> interpolator_cr(std::move(points_intr));
auto max_s = interpolator_cr.max_parameter(); std::array<double, 2> inter_points; for (int i = 0; i < 100; i++) { inter_points = interpolator_cr(max_s * (i / num_points)); geometry_msgs::Point p; p.x = inter_points[0]; p.y = inter_points[1]; p.z = z; //p.z = inter_points[2]; marker.points.push_back(p); DEBUG_INFO("spline %d: (x, y) %f, %f, current_s: %f", i, p.x, p.y, max_s * (i / 100.0)); }
I'm using boost 1.71.0
-- Sent from: http://boost.2283326.n4.nabble.com/Boost-Users-f2553780.html _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org https://lists.boost.org/mailman/listinfo.cgi/boost-users

On 30/09/2019 01:46, hgrwilson via Boost-users wrote:
Hi all,
I am trying to interpolate some data with a *catmull_rom* spline available in boost math (interpolation). However, the resulting spline collapses to a single point for all /s/, corresponding to the first control point, /points_intr[0]/.
You're code is *almost* correct, but there is a critical bug: the division (i / num_points) is all-integer-division and so always produces the result 0. Change the call to interpolator_cr((max_s * i) / num_points) and everything is just fine: with 50 points the output I get is: 1.26327 0.774614 1.29431 1.08369 1.56807 1.64688 1.83203 2.27479 1.89198 2.84116 1.8401 3.44126 1.74119 4.03594 1.64816 4.569 1.55777 5.00992 1.46654 5.41294 1.41084 5.84666 1.37552 6.3168 1.38638 6.79263 1.4794 7.25428 1.64023 7.72351 1.88209 8.15832 2.23047 8.50515 2.70565 8.76054 3.26229 8.95583 3.84499 9.12174 4.43925 9.26314 5.07198 9.36489 5.72189 9.44657 6.36711 9.52815 7.00053 9.61229 7.63445 9.68771 8.26827 9.76416 8.90127 9.85153 9.55104 9.95554 10.2167 10.0706 10.8575 10.1904 11.4326 10.3088 11.9145 10.4206 12.3401 10.5325 12.7656 10.6563 13.2034 10.7926 13.64 10.9415 14.079 11.1098 14.5235 11.2964 14.9685 11.5024 15.4066 11.732 15.8379 11.9667 16.2635 12.23 16.6819 12.5679 17.1204 13.0333 17.572 13.5993 17.9852 14.1927 18.3084 14.7404 18.5503 15.2575 18.7269 15.7653 18.7 16.056 As ever, a little debugging goes a long way... HTH, John.
Below, the c++ code segment of the interpolation is depicted:
std::vector<std::array<double, 2>> points_intr(16);
points_intr[0] = { 1.263270, 0.774614 }; points_intr[1] = { 1.876, 2.480 }; points_intr[2] = { 1.651110, 4.550 }; points_intr[3] = { 1.426340, 5.688 }; points_intr[4] = { 1.429, 7.054 }; points_intr[5] = { 2.073220, 8.377020 }; points_intr[6] = { 3.910, 9.140 }; points_intr[7] = { 6.430, 9.537 }; points_intr[8] = { 8.950, 9.859 }; points_intr[9] = { 11.470, 10.317 }; points_intr[10] = { 12.730, 10.6456 }; points_intr[11] = { 13.990, 11.0741 }; points_intr[12] = { 15.335, 11.6928 }; points_intr[13] = { 16.680, 12.5661 }; points_intr[14] = { 18.3538, 14.830 }; points_intr[15] = { 18.700, 16.056 };
boost::math::catmull_rom<std::array<double, 2>> interpolator_cr(std::move(points_intr));
auto max_s = interpolator_cr.max_parameter(); std::array<double, 2> inter_points; for (int i = 0; i < 100; i++) { inter_points = interpolator_cr(max_s * (i / num_points)); geometry_msgs::Point p; p.x = inter_points[0]; p.y = inter_points[1]; p.z = z; //p.z = inter_points[2]; marker.points.push_back(p); DEBUG_INFO("spline %d: (x, y) %f, %f, current_s: %f", i, p.x, p.y, max_s * (i / 100.0)); }
I'm using boost 1.71.0
-- Sent from: http://boost.2283326.n4.nabble.com/Boost-Users-f2553780.html _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org https://lists.boost.org/mailman/listinfo.cgi/boost-users
--- This email has been checked for viruses by Avast antivirus software. https://www.avast.com/antivirus

The problem is in this line: inter_points = interpolator_cr(max_s * (i / num_points)); i/num_points rounds to zero. I just reproduced your code with the fix: #include <iostream> #include <boost/math/interpolators/catmull_rom.hpp> #include <vector> #include <array> int main() { std::vector<std::array<double, 2>> points_intr(16); points_intr[0] = { 1.263270, 0.774614 }; points_intr[1] = { 1.876, 2.480 }; points_intr[2] = { 1.651110, 4.550 }; points_intr[3] = { 1.426340, 5.688 }; points_intr[4] = { 1.429, 7.054 }; points_intr[5] = { 2.073220, 8.377020 }; points_intr[6] = { 3.910, 9.140 }; points_intr[7] = { 6.430, 9.537 }; points_intr[8] = { 8.950, 9.859 }; points_intr[9] = { 11.470, 10.317 }; points_intr[10] = { 12.730, 10.6456 }; points_intr[11] = { 13.990, 11.0741 }; points_intr[12] = { 15.335, 11.6928 }; points_intr[13] = { 16.680, 12.5661 }; points_intr[14] = { 18.3538, 14.830 }; points_intr[15] = { 18.700, 16.056 }; boost::math::catmull_rom<std::array<double, 2>> interpolator_cr(std::move(points_intr)); auto max_s = interpolator_cr.max_parameter(); std::array<double, 2> inter_points; for (int i = 0; i < 100; i++) { double arg = max_s*i/double(100); inter_points = interpolator_cr(arg); std::cout << "p(" << arg << ") = (" << inter_points[0] << ", " << inter_points[1] << ")\n"; } } No need to normalize your data. Nick ‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐ On Sunday, September 29, 2019 8:46 PM, hgrwilson via Boost-users <boost-users@lists.boost.org> wrote:
Hi all,
I am trying to interpolate some data with a catmull_rom spline available in boost math (interpolation). However, the resulting spline collapses to a single point for all /s/, corresponding to the first control point, /points_intr[0]/.
Below, the c++ code segment of the interpolation is depicted:
std::vector<std::array<double, 2>> points_intr(16);
points_intr[0] = { 1.263270, 0.774614 }; points_intr[1] = { 1.876, 2.480 }; points_intr[2] = { 1.651110, 4.550 }; points_intr[3] = { 1.426340, 5.688 }; points_intr[4] = { 1.429, 7.054 }; points_intr[5] = { 2.073220, 8.377020 }; points_intr[6] = { 3.910, 9.140 }; points_intr[7] = { 6.430, 9.537 }; points_intr[8] = { 8.950, 9.859 }; points_intr[9] = { 11.470, 10.317 }; points_intr[10] = { 12.730, 10.6456 }; points_intr[11] = { 13.990, 11.0741 }; points_intr[12] = { 15.335, 11.6928 }; points_intr[13] = { 16.680, 12.5661 }; points_intr[14] = { 18.3538, 14.830 }; points_intr[15] = { 18.700, 16.056 };
boost::math::catmull_rom<std::array<double, 2>> interpolator_cr(std::move(points_intr));
auto max_s = interpolator_cr.max_parameter(); std::array<double, 2> inter_points;
for (int i = 0; i < 100; i++) { inter_points = interpolator_cr(max_s * (i / num_points)); geometry_msgs::Point p; p.x = inter_points[0]; p.y = inter_points[1]; p.z = z; //p.z = inter_points[2]; marker.points.push_back(p); DEBUG_INFO("spline %d: (x, y) %f, %f, current_s: %f", i, p.x, p.y, max_s * (i / 100.0)); }
I'm using boost 1.71.0
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Sent from: http://boost.2283326.n4.nabble.com/Boost-Users-f2553780.html
Boost-users mailing list Boost-users@lists.boost.org https://lists.boost.org/mailman/listinfo.cgi/boost-users
participants (4)
-
Giorgino R
-
hgrwilson
-
John Maddock
-
Nick Thompson