catmull_rom returning a single point

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

catmull_rom returning a single point

Boost - Users mailing list
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&lt;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&lt;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
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: catmull_rom returning a single point

Boost - Users mailing list
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 <[hidden email]> 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&lt;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&lt;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
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boost-users

_______________________________________________
Boost-users mailing list
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: catmull_rom returning a single point

Boost - Users mailing list
In reply to this post by Boost - Users mailing list

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&lt;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&lt;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
> [hidden email]
> 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

_______________________________________________
Boost-users mailing list
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: catmull_rom returning a single point

Boost - Users mailing list
In reply to this post by Boost - Users mailing list
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 <[hidden email]> 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
> [hidden email]
> https://lists.boost.org/mailman/listinfo.cgi/boost-users


_______________________________________________
Boost-users mailing list
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boost-users