美文网首页
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