【问题标题】:Smooth Interpolation between two points两点之间的平滑插值
【发布时间】:2016-08-27 17:43:11
【问题描述】:

我正在尝试在点之间的网格中进行插值。我做了一些研究并找到了很少的解决方案,但它们都对我产生了奇怪的结果。我尝试了 Cosinus 和 Cubic 插值,但整个网格中会出现微小的波浪,而不是平滑。

我试过了

 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);

从这里:http://paulbourke.net/miscellaneous/interpolation/

我得到了我需要的所有积分,并且一切都应该正常工作,但事实并非如此。我花了很多时间调试它,我发现唯一的问题是,似乎 mu(插值中从 0.0 到 1.0 的常规 t)在 P1 开始时应该是 0.0,但在 P3 时是 1.0,而它应该在P2(点P0,P1,P2,P3,插值应该发生在P1和P2之间)

如果有任何其他更好的简单方法可以在两点之间进行插值,请告诉我。我不想用控制点做贝塞尔曲线或类似的事情。我只有两点,我可以像上面的例子一样在每一边再使用一个点。

感谢您的帮助 卢克

【问题讨论】:

  • 您可能想使用Catmull-Rom spline
  • 谢谢您,先生,这就像一个魅力。如果可以的话,我会将其标记为正确答案。

标签: interpolation curve points smooth cubic


【解决方案1】:

Catmull-Rom 样条似乎适合您的数据。

作为在 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

根据您的需要,您可能会发现Catmull-rom curve with no cusps and no self-intersections 很有用。

【讨论】:

    猜你喜欢
    • 2012-07-14
    • 2020-03-29
    • 2013-12-19
    • 1970-01-01
    • 2021-06-10
    • 2019-08-20
    • 1970-01-01
    • 1970-01-01
    • 2014-03-17
    相关资源
    最近更新 更多