贝齐尔工作不正常

时间:2014-08-21 11:28:37

标签: c# unity3d bezier

我试图在我的Unity游戏中实现一个简单的bezier曲线,但似乎没有用。 这是如何绘制的截图:

enter image description here

4个绿色球体是Bezier的枢轴,白色球体是计算出来的实际贝塞尔曲线。如你所见,它有点不正确。

这是我的bezier代码(我从Unity的论坛中获取):

using UnityEngine;

[System.Serializable]
public class Bezier : System.Object
{

    public Vector3 p0;
    public Vector3 p1;
    public Vector3 p2;
    public Vector3 p3;

    public float ti = 0f;

    private Vector3 b0 = Vector3.zero;
    private Vector3 b1 = Vector3.zero;
    private Vector3 b2 = Vector3.zero;
    private Vector3 b3 = Vector3.zero;

    private float Ax;
    private float Ay;
    private float Az;

    private float Bx;
    private float By;
    private float Bz;

    private float Cx;
    private float Cy;
    private float Cz;

    // Init function v0 = 1st point, v1 = handle of the 1st point , v2 = handle of the 2nd point, v3 = 2nd point
    // handle1 = v0 + v1
    // handle2 = v3 + v2
    public Bezier( Vector3 v0, Vector3 v1, Vector3 v2, Vector3 v3 )
    {
        this.p0 = v0;
        this.p1 = v1;
        this.p2 = v2;
        this.p3 = v3;
    }

    // 0.0 >= t <= 1.0
    public Vector3 GetPointAtTime( float t )
    {
        this.CheckConstant();
        float t2 = t * t;
        float t3 = t * t * t;
        float x = this.Ax * t3 + this.Bx * t2 + this.Cx * t + p0.x;
        float y = this.Ay * t3 + this.By * t2 + this.Cy * t + p0.y;
        float z = this.Az * t3 + this.Bz * t2 + this.Cz * t + p0.z;
        return new Vector3( x, y, z );

    }

    private void SetConstant()
    {
        this.Cx = 3f * ( ( this.p0.x + this.p1.x ) - this.p0.x );
        this.Bx = 3f * ( ( this.p3.x + this.p2.x ) - ( this.p0.x + this.p1.x ) ) - this.Cx;
        this.Ax = this.p3.x - this.p0.x - this.Cx - this.Bx;

        this.Cy = 3f * ( ( this.p0.y + this.p1.y ) - this.p0.y );
        this.By = 3f * ( ( this.p3.y + this.p2.y ) - ( this.p0.y + this.p1.y ) ) - this.Cy;
        this.Ay = this.p3.y - this.p0.y - this.Cy - this.By;

        this.Cz = 3f * ( ( this.p0.z + this.p1.z ) - this.p0.z );
        this.Bz = 3f * ( ( this.p3.z + this.p2.z ) - ( this.p0.z + this.p1.z ) ) - this.Cz;
        this.Az = this.p3.z - this.p0.z - this.Cz - this.Bz;

    }

    // Check if p0, p1, p2 or p3 have changed
    private void CheckConstant()
    {
        if( this.p0 != this.b0 || this.p1 != this.b1 || this.p2 != this.b2 || this.p3 != this.b3 )
        {
            this.SetConstant();
            this.b0 = this.p0;
            this.b1 = this.p1;
            this.b2 = this.p2;
            this.b3 = this.p3;
        }
    }
}

这是我的实现脚本(它在场景中的空游戏对象上):

public class arrowPath : MonoBehaviour {
    public Transform[] pontos=new Transform[4];
    public Bezier bezier;

    // Use this for initialization
    void Start () {
    }

    // Update is called once per frame
    void Update () {
        bezier=new Bezier(pontos[0].position, pontos[1].position, pontos[2].position, pontos[3].position);

        for(float u= 0.0f; u<=1.0f; u+=0.05f)
        {
            Graphics.DrawMesh(pontos[0].GetComponent<MeshFilter>().sharedMesh, bezier.GetPointAtTime(u), Quaternion.Euler(Vector3.zero), pontos[0].renderer.sharedMaterial, 0);
        }
    }
}

&#34; pontos&#34; array是Transform数组以保存球体。我通过Unity的检查员填写。

我感谢任何帮助。

感谢。

1 个答案:

答案 0 :(得分:2)

看起来非常像GetPointAtTime旨在生成贝塞尔点。如果是这样的话,你根本就没有评估正确的函数:对于一个三次贝塞尔曲线,函数是:

a ‧ t³ + 3 ‧ b ‧ t² ‧ (1-t) + 3 ‧ c ‧ t ‧ (1-t)² + d ‧ (1-t)³

因此,您的代码不使用二项式,它只是使用t的直接多项式,它会产生非常错误的东西=)

所以,改变你的功能:

public float ComputeBezierValue( float t, float a, float b, float c, float d )
{
    float t2 = t * t,
          t3 = t2 * t,
          mt = 1 - t,
          mt2 = mt * mt,
          mt3 = mt2 * mt;
    return a * t3 + 3 * b * t2 * mt + 3 * c * t * mt2 + d * mt3;
}

public Vector3 GetPointAtTime( float t )
{
    this.CheckConstant();
    float x = ComputeBezierValue(t, this.Ax, this.Bx, this.Cx, this.Dx);
    float y = ComputeBezierValue(t, this.Ay, this.By, this.Cy, this.Dy);
    float z = ComputeBezierValue(t, this.Az, this.Bz, this.Cz, this.Dz);
    return new Vector3( x, y, z );
}

另请注意,我已经写过这个以明确使用四个坐标。 Cubic Bezier曲线需要全部四个,Quadratic只使用三个(但通常很差,表示均匀弯曲的段,如圆形/椭圆形段,以及sinoids)