美文网首页
2020-06-18【Math|转】插值与样条--Catmull

2020-06-18【Math|转】插值与样条--Catmull

作者: 持刀的要迟到了 | 来源:发表于2020-06-19 11:18 被阅读0次

()https://www.cnblogs.com/WhyEngine/p/4020294.html?tdsourcetag=s_pctim_aiomsg

  • 插值:已知点列,并且完全经过点列
    通过函数,在有限个点处的取值情况,估算出函数在其他点处的近似值。
    插值可以用于填充图像变换时,像素之间的空隙。
  • 拟合:已知点列,从整体上靠近他们

  • 逼近:已知曲线,或者点列,通过逼近使得构造函数无线靠近他们。

科学和工程问题,可以通过诸如采样、实验等方法获得若干离散的数据,根据这些数据,我们往往希望得到一个连续的函数(曲线)或者更加密集的离散方程与已知数据吻合。

定义:
1.

点P 代表一个点
曲线片段C由 point P0,P1,P2,P3和knot sequence t0,t1,t2,t3定义。
曲线可以这样产生:
曲线C定义
A、B定义
t定义
t0 = 0
t1 = (p0到p1的长度)^a + t0;当a为0,则t1为t0长度;当a为1,则t1为两点距离+t0长度
因此t是 点距离^a次方 的叠加值
a==0:uniform Catmull-Rom spline(统一的)
a==1:chordal Catmull-Rom spline(和弦的)
a==0.5:centripetal Catmull-Rom spline(向心的)

把t=t1插入样条方程A1A2A3B1B2,可以获得曲线C=P1。同样地,t=t2则C=P2。
t就是曲线的变量,而且能够保证t=t1时通过点P1

向心卡特穆尔-罗姆样条与原来的卡特穆尔-罗姆公式和其他类型的卡特穆尔-罗姆公式相比,有几个理想的数学特性。首先,它不会在曲线段内形成循环或自交。第二,在曲线段内永远不会出现尖点。第三,更紧密地跟随控制点。
在计算机视觉中,向心Catmull-Rom样条被用来制定一个主动的分割模型。这种方法称为主动样条模型。[4]模型是在主动形状模型的基础上设计的,但采用向心卡特穆尔- rom样条曲线连接连续的两个点(主动形状模型采用简单的直线),这样描述一个形状所需的总点数较少。向心Catmull-Rom样条的使用使得形状模型的训练变得更加简单,并且可以更好地编辑分割后的轮廓。


using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class Catmul : MonoBehaviour {

    // Use the transforms of GameObjects in 3d space as your points or define array with desired points
    public Transform[] points;
    
    // Store points on the Catmull curve so we can visualize them
    List<Vector2> newPoints = new List<Vector2>();
    
    // How many points you want on the curve
    uint numberOfPoints = 10;
    
    // Parametric constant: 0.0 for the uniform spline, 0.5 for the centripetal spline, 1.0 for the chordal spline
    public float alpha = 0.5f;
    
    /////////////////////////////
    
    void Update()
    {
        CatmulRom();
    }
    
    void CatmulRom()
    {
        newPoints.Clear();

        Vector2 p0 = points[0].position; // Vector3 has an implicit conversion to Vector2
        Vector2 p1 = points[1].position;
        Vector2 p2 = points[2].position;
        Vector2 p3 = points[3].position;

        float t0 = 0.0f;
        float t1 = GetT(t0, p0, p1);
        float t2 = GetT(t1, p1, p2);
        float t3 = GetT(t2, p2, p3);

        for (float t=t1; t<t2; t+=((t2-t1)/(float)numberOfPoints))
        {
            Vector2 A1 = (t1-t)/(t1-t0)*p0 + (t-t0)/(t1-t0)*p1;
            Vector2 A2 = (t2-t)/(t2-t1)*p1 + (t-t1)/(t2-t1)*p2;
            Vector2 A3 = (t3-t)/(t3-t2)*p2 + (t-t2)/(t3-t2)*p3;
            
            Vector2 B1 = (t2-t)/(t2-t0)*A1 + (t-t0)/(t2-t0)*A2;
            Vector2 B2 = (t3-t)/(t3-t1)*A2 + (t-t1)/(t3-t1)*A3;
            
            Vector2 C = (t2-t)/(t2-t1)*B1 + (t-t1)/(t2-t1)*B2;
            
            newPoints.Add(C);
        }
    }

    float GetT(float t, Vector2 p0, Vector2 p1)
    {
        float a = Mathf.Pow((p1.x-p0.x), 2.0f) + Mathf.Pow((p1.y-p0.y), 2.0f);
        float b = Mathf.Pow(a, alpha * 0.5f);
       
        return (b + t);
    }
    
    // Visualize the points
    void OnDrawGizmos()
    {
        Gizmos.color = Color.red;
        foreach (Vector2 temp in newPoints)
        {
            Vector3 pos = new Vector3(temp.x, temp.y, 0);
            Gizmos.DrawSphere(pos, 0.3f);
        }
    }
}

相关文章

网友评论

      本文标题:2020-06-18【Math|转】插值与样条--Catmull

      本文链接:https://www.haomeiwen.com/subject/vjtuxktx.html