有时候,我们需要在世界空间中绘制一个优美的曲线做预览使用,在U3d的世界场景中,可以通过LineRender组件绘制线模型。此组件需要传入线段的拐点。曲线的原理就是拥有非常细腻度的插值拐点,所以,我们能通过计算的方式插值出点,从而设置金融业LineRender中。

贝塞尔曲线,至少需要3个点,一个启点,一个控制点,一个终点。我们绘制的线段中不可能只会有3个点,比如现在有6个点,需要绘制连续的无明显拐点尖叫的曲线怎么做呢。

我这里做了一个简单的祛除尖端的处理,比如3个点,也就是2个线段,分别是p1p2,p2p3。现在我们求得p1p2的中点ps,p2p3的中点pe。然后把ps,p2,pe作为贝塞尔曲线的控制点进行计算。我这里采用2次贝塞尔曲线公式,函数如:

    Vector3 GetLerpCurve(Vector3 p1, Vector3 p2, Vector3 p3, float t)
    {
        Vector3 d = (1 - t) * (1 - t) * p1 + 2 * (1 - t) * t * p2 + t * t * p3;
        return d;
    }

t是一个[0,1]的值,所以,我们可以根据精度需要把曲线分成多少段。

整个曲线点的插值函数如:

public void SetLinePositions(Vector3[] positions)
    {
        this.positions = positions;
        if (lineRender == null)
        {
            return;
        }
        if (positions.Length < 3)
        {
            lineRender.positionCount = positions.Length;
            lineRender.SetPositions(positions);
            return;
        }
        int index = 0;
        List<Vector3> result = new List<Vector3>();
        result.Add(positions[index]);
        while (index <= positions.Length - 3)
        {
            Vector3 p1 = positions[index];
            Vector3 p2 = positions[index + 1];
            Vector3 p3 = positions[index + 2];
            Vector3 p11 = (p1 + p2) / 2;
            Vector3 p33 = (p2 + p3) / 2;
            index += 1;

            //每次向前推移一个节点,继续插值,这样就能多顶点连续曲线
            for (int i = 0; i < sampleCount; ++i)
            {
                float t = i * 1.0f / sampleCount;
                Vector3 p = GetLerpCurve(p11, p2, p33, t);
                result.Add(p);
            }


        }
        result.Add(positions[positions.Length - 1]);
        lineRender.positionCount = result.Count;
        lineRender.SetPositions(result.ToArray());
    }

其中lineRender是LineRenderer组件,我们这里只需要设置折线的各个拐点坐标,就能通过贝塞尔插值的方式把拐角磨平滑。最后的表现效果如:

希望此分享,对看见者有所帮助。