msteinbeck / tinyspline

ANSI C library for NURBS, B-Splines, and Bézier curves with interfaces for C++, C#, D, Go, Java, Javascript, Lua, Octave, PHP, Python, R, and Ruby.
MIT License
1.19k stars 207 forks source link

How to make a smooth closed interpolation? #111

Open yiroro opened 6 years ago

yiroro commented 6 years ago

I'm trying to fit a set of data points with a closed B-spline using ts_bspline_interpolate_cubic(), but the resulted curve is not smooth at the joining point. Is there any way to generate a smooth interpolated curve?

msteinbeck commented 6 years ago

Hallo @Yiroro,

Currently, only the natural spline interpolation approach has been implemented. What you are looking for is called periodic spline interpolation where the first and the last control point have the same location. Unfortunately, I don't know any C library which provides this method out of the box :(.

msteinbeck commented 6 years ago

I close this issue for now. Don't hesitate to reopen.

rothos commented 1 year ago

Hello @msteinbeck, thank you so much for creating and maintaining this tool. It's fantastic.

I add my name to the list of people who would love support for periodic interpolation.

I did come up with a hacky and inefficient way to make splines that are approximately periodic, but it doesn't do interpolation at the moment... if S is a spline I want to make periodic, I first create a new spline T out of several (5 seems to work well) endpoint-to-endpoint copies of S. Then I interpolate T at some points to create P, and finally take a subspline S' of P corresponding to of the middle copy of S in T. Using this method I've been able to create a nearly-periodic version of splines. Rescaling is sometimes necessary at the end to minimize e.g. ||S - S'||^2.

Here is a picture. At the top is the original spline S which I want to make periodic. Below is T in black and P in blue. The green points (t = 3/8 and t = 5/8 here, found empirically) are where the subspline S' was cut from P:

Screenshot 2023-03-15 at 21 58 36

As you can see, rescaling is needed to make S' more closely approximate S. I didn't do much thinking about what the best interpolation points were, which also could be optimized.

However, the derivatives at the endpoints of the resultant spline are nearly identical, as desired:

89.99998766184565, -45.00021591781601
89.99998122455591, -45.00036075709994
msteinbeck commented 1 year ago

Hi @rothos,

thank you so much for creating and maintaining this tool. It's fantastic.

Thank you. Nice to see that this project is also useful for others.

I add my name to the list of people who would love support for periodic interpolation.

I did some research in the last years and found the following document: https://mirror.math.princeton.edu/pub/CTAN/graphics/pstricks/contrib/pst-bspline/pst-bspline-doc.pdf. On page 13 (Section 5.2: Closed (periodic) case) it shows the matrix that needs to be solved for cubic periodic spline interpolation. On pages 14--15 some pseudo-code is provided to implement this approach. It basically solves this matrix with Gaussian elimination (if I remember correctly). Although I know how to implement this kind of interpolation, I didn't find the time yet (also had no need for it yet). Anyhow, I will try to implement your request in the next days.