Reputation: 1514
i am trying to interpolate in a mesh between points. I did some research and found few solutions, but all of them produce weird results for me. I tried Cosinus and Cubic interpolation, but whole mesh gets tiny waves in it instead of being smooth.
I tried this
mu2 = mu*mu;
a0 = y3 - y2 - y0 + y1;
a1 = y0 - y1 - a0;
a2 = y2 - y0;
a3 = y1;
return(a0*mu*mu2+a1*mu2+a2*mu+a3);
from here : http://paulbourke.net/miscellaneous/interpolation/
i got all the points i need and all should be working, but it isnt. I spent a lot of time debugging it and only thing i found to be a problem is that it seems that mu ( regular t from 0.0 - 1.0 in interpolation ) starts at 0.0 at P1 as it should, but at 1.0 it is at P3, while it should be at P2 ( points P0, P1, P2, P3, where interpolation should happen between P1 and P2 )
If there is any other better simple way how to do interpolation between two points, please let me know. I dont want to do bezier curves or anything like that with controls points. I just have two points and i can use one more point on each side like in the example above.
Thanks for any help Luke
Upvotes: 0
Views: 1355
Reputation: 25023
It appears that a Catmull-Rom spline would be suitable for your data.
As an example of implementing it in VB.NET:
Module Module1
''' <summary>
''' A class for a 2-D point and operations on it.
''' </summary>
Class PointD
Property X As Double
Property Y As Double
Public Shared Operator +(p1 As PointD, p2 As PointD) As PointD
Return New PointD(p1.X + p2.X, p1.Y + p2.Y)
End Operator
Public Shared Operator -(p As PointD) As PointD
Return New PointD(-p.X, -p.Y)
End Operator
Public Shared Operator -(p1 As PointD, p2 As PointD) As PointD
Return New PointD(p1.X - p2.X, p1.Y - p2.Y)
End Operator
Public Shared Operator *(a As Double, p As PointD) As PointD
Return New PointD(a * p.X, a * p.Y)
End Operator
Public Shared Operator *(p As PointD, a As Double) As PointD
Return New PointD(a * p.X, a * p.Y)
End Operator
'TODO: (Optional) Add methods for magnitude, cross product and dot product.
Public Sub New()
' empty contructor
End Sub
Public Sub New(x As Double, y As Double)
Me.X = x
Me.Y = y
End Sub
Public Overrides Function ToString() As String
' use the N3 format string for tidiness in this example
Return $"({X:N3}, {Y:N3})"
End Function
End Class
''' <summary>
''' Ordinary Catmull-Rom interpolation.
''' </summary>
''' <param name="t">Vary from 0.0 to 1.0 to get an interpolated point between data points p1 and p2.</param>
''' <param name="p0">The first control point.</param>
''' <param name="p1">The first data point.</param>
''' <param name="p2">The second data point.</param>
''' <param name="p3">The second control point.</param>
''' <returns>The interpolated point.</returns>
Function CatmullRomInterpolate(t As Double, p0 As PointD, p1 As PointD, p2 As PointD, p3 As PointD) As PointD
' this is the regular Catmull-Rom spline
' other ways of treating it can be found at:
' https://stackoverflow.com/questions/9489736/catmull-rom-curve-with-no-cusps-And-no-self-intersections
Return 0.5 * ((2 * p1) +
t * (p2 - p0) +
Math.Pow(t, 2) * (2 * p0 - 5 * p1 + 4 * p2 - p3) +
Math.Pow(t, 3) * (3 * (p1 - p2) + p3 - p0))
End Function
Sub Main()
' some sample data which will produce a symmetrical wave shape...
Dim p0 As New PointD(-1, 1)
Dim p1 As New PointD(0, 0)
Dim p2 As New PointD(1, 0)
Dim p3 As New PointD(2, -1)
For t = 0.0 To 1.0 Step 0.1
Console.WriteLine(CatmullRomInterpolate(t, p0, p1, p2, p3))
Next
Console.ReadLine()
End Sub
End Module
Depending on what you need, you might find Catmull-rom curve with no cusps and no self-intersections useful.
Upvotes: 2