#StackBounty: #mathematics #spline Cubic Splines – Do Parametric and Explicit representation give different curves?

Bounty: 100

I asked a similar question here before but since the previous post original question was different, I think it was confusing people. So I’ve voted to close that and asking the new question here. I’m doing a volume rendering project and made a cubic spline editor for transfer function. I used this as a source which basically uses Wolfram as the main source. Now Wolfram defines a parametric representation. After I made it, I tried to compare it online but the curves are different. The only difference I found is that the online version is using a non-parametric representation.

Here’s mine.
enter image description here

And here’s the online version
enter image description here

In order to clarify a bit more on what I’m trying to do. I have 2 variables.

$X = [0, 255] $

$Y = [0, 1] $

For every given $X$ value I need the interpolated $Y$ value. At first glance it seems that the explicit form of cubic spline is what I want. But I have another case where $Y$ values are RGB triplets $(r,g,b)$. Since the parametric representation doesn’t have to deal with dimensions and since the code was already online I’m using the parametric form. The parametric form uses the parameter $t in [0,1]$ for every segment.

Now things get a little trickier. Technichally my graph is of $(t, Y(t))$ but as you can see in the first picture the X-axis isn’t $t$ but the previously defined $X$ which is in range $[0-255]$. I’m simply rescaling between $X$ and $t$. So if I get $t = 0.5$ for the first segment as an example, I’d take the two bounding control points which resolve to $(0,0)$ and $(141, 0.759)$ in the first picture. Then do simple rescaling like

$0 + (141 – 0) * t$

to get my iso-value and plot the graph. Here’s how I’m actually drawing the graph

float t_step = 1/255.0f;
for(int i = 0; i < knots.size() - 1; i++)
  {
    for (int i_step = 1; i_step <= num_line_segments; i_step++)
    {
        glm::vec2 coord;
        coord.x = knots[i].iso_value + (t_step * i_step * (knots[i+1].iso_value - knots[i].iso_value));
        coord.y = glm::clamp(alpha_spline.getPointOnSpline(t_step * i_step, i).w, v_min.y, v_max.y);
        win->DrawList->_Path.push_back(getAbsMousePositionFromPoint(coord) );
    }
  }
  
getAbsMousePositionFromPoint(glm::vec2 v)
{
  glm::vec2 v_min(0,0), v_max(255, 1.0)
  glm::vec2 t = (v - v_min) / (v_max - v_min);
  return glm::mix(graph_bot_left, graph_top_right, t);   // both "graph_bot_left" and "graph_top_right" are absolute coordinates of the drawing region
}

Basically I need absolute coordinates for drawing anything on the screen. Each segment of the spline is basically drawn as a polyline. Just to be on the safe side I have currently set the number of line segments per curve of the spline to be 255. This means per segment of the spline I need to draw 255 line segments. I step along t then transform it to the proper X-value by doing the transformation step as I told above then find absolute coordinates from that X-value and draw the segment there.

Now all I wanna know is, do parametric and explicit forms give different curves? If not, then is there something wrong with the rescaling step I’m doing above or something else?

P.S :- I’ve checked the formulation and the boundary conditions of the online one and all are similar to the Wolfram one. Both mine and the online one are natural cubic splines. I’ve also double checked my code, even derived the whole parametric form on paper and checked the code with the one derived on paper and it matches perfectly so I’m pretty sure the code isn’t wrong. Still here’s my spline source as a reference if anybody here knows programming

UPDATE:- So I just found another guy using the same logic as well here. I guess the math is all right then. Don’t see where’s the problem then.


Get this bounty!!!

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.