Unity 工具类 之 贝塞尔 Bezier 曲线

Unity 工具类 之 贝塞尔 Bezier 曲线

 

目录

Unity 工具类 之 贝塞尔 Bezier 曲线

一、简单介绍

二、原理与分类

三、公式与原理图演示

五、注意事项

六、样例使用步骤(三次贝塞尔方程曲线)

七、代码


 

一、简单介绍

贝塞尔曲线是最基本的曲线,一般用在计算机 图形学和 图像处理。贝塞尔曲线可以用来创建平滑的曲线的道路、 弯曲的路径就像 祖玛游戏、 弯曲型的河流等。

 

二、原理与分类

贝塞尔曲线返回点的贝塞尔函数,使用线性插值的概念作为基础。

 一条贝塞尔曲线是由一组定义的控制点 P0到 Pn,在 n 调用它的顺序 (n = 1 为线性,2 为二次,等.)。第一个和最后一个控制点总是具有终结点的曲线;然而,中间两个控制点 (如果有的话) 一般不会位于曲线上 。

(1)贝塞尔曲线包含两个控制点即 n = 2 称为线性的贝塞尔曲线

(2)贝塞尔曲线包含三个控制点即 n = 3 称为二次贝塞尔曲线

(3)贝塞尔曲线包含四个控制点即 n = 4,所以称为三次贝塞尔曲线。


三、公式与原理图演示

1.线性贝塞尔公式:

给定点P0、P1,线性贝兹曲线只是一条两点之间的直线。这条线由下式给出:

其等同于线性插值。

2.二次贝塞尔公式:

二次方贝兹曲线的路径由给定点P0、P1、P2控制,这条线由下式给出:

3.三次贝塞尔方程:

P0、P1、P2、P3四个点在平面或在三维空间中定义了三次方贝兹曲线。曲线起始于P0走向P1,并从P2的方向来到P3。一般不会经过P1或P2;这两个点只是用来充当控制点。P0和P1之间的间距,决定了曲线在转而趋进P3之前,走向P2方向的“长度有多长”。

曲线的参数形式为:

4.一般参数形式的贝塞尔方程:

 N阶贝兹曲线可如下推断。给定点P0、P1、…、Pn,其贝兹曲线即:

如上公式可如下递归表达: 用表示由点P0、P1、…、Pn所决定的贝兹曲线。

 

五、注意事项

1、通过两个低阶的贝塞尔曲线插值的堆叠总能够获得更高阶的贝塞尔曲线,通俗的来说通过对两条低阶的贝塞尔曲线插值,你可以求得一条高一阶的贝塞尔曲线。

2、二次贝塞尔曲线是点对点的两个线性贝塞尔曲线的线性插值,三次贝塞尔曲线是两条二次贝塞尔曲线的线性插值。
 

六、样例使用步骤(三次贝塞尔方程曲线)

1、打开Unity,新建一个场景,里面 添加一些球体,作为贝塞尔曲线点,如下图

2、新建贝塞尔接口脚本,和调用脚本,调用脚本挂载到 BezierDemo 物体上,并把球体依次赋值,如下图

3、运行场景,三次贝塞尔曲线效果,如下图

 

七、代码

1、BezierDemo 代码

using UnityEngine;

[RequireComponent(typeof(LineRenderer))]
public class BezierDemo : MonoBehaviour
{
    // 三次贝塞尔控制点
    public Transform[] controlPoints;

    // LineRenderer 
    private LineRenderer lineRenderer;
    private int layerOrder = 0;

    // 设置贝塞尔插值个数
    private int _segmentNum = 50;   


    void Start()
    {
        if (!lineRenderer)
        {
            lineRenderer = GetComponent<LineRenderer>();
        }
        lineRenderer.sortingLayerID = layerOrder;

    }

    void Update()
    {

        DrawThreePowerCurve();

    }


    Vector3[] points3;
    void DrawThreePowerCurve()
    {
        // 获取三次贝塞尔方程曲线
        points3 = BezierUtils.GetThreePowerBeizerList(controlPoints[0].position, controlPoints[1].position, controlPoints[2].position, controlPoints[3].position, _segmentNum);
        // 设置 LineRenderer 的点个数,并赋值点值
        lineRenderer.positionCount = (_segmentNum);
        lineRenderer.SetPositions(points3);

    }

}

 

2、BezierUtils 代码

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

public class BezierUtils
{

    /// <summary>
    /// 线性贝塞尔曲线,根据T值,计算贝塞尔曲线上面相对应的点
    /// </summary>
    /// <param name="t"></param>T值
    /// <param name="p0"></param>起始点
    /// <param name="p1"></param>控制点
    /// <returns></returns>根据T值计算出来的贝赛尔曲线点
    private static Vector3 CalculateLineBezierPoint(float t, Vector3 p0, Vector3 p1)
    {
        float u = 1 - t;
         
        Vector3 p = u * p0;
        p +=  t * p1;
    

        return p;
    }

    /// <summary>
    /// 二次贝塞尔曲线,根据T值,计算贝塞尔曲线上面相对应的点
    /// </summary>
    /// <param name="t"></param>T值
    /// <param name="p0"></param>起始点
    /// <param name="p1"></param>控制点
    /// <param name="p2"></param>目标点
    /// <returns></returns>根据T值计算出来的贝赛尔曲线点
    private static Vector3 CalculateCubicBezierPoint(float t, Vector3 p0, Vector3 p1, Vector3 p2)
    {
        float u = 1 - t;
        float tt = t * t;
        float uu = u * u;

        Vector3 p = uu * p0;
        p += 2 * u * t * p1;
        p += tt * p2;

        return p;
    }

    /// <summary>
    /// 三次贝塞尔曲线,根据T值,计算贝塞尔曲线上面相对应的点
    /// </summary>
    /// <param name="t">插量值</param>
    /// <param name="p0">起点</param>
    /// <param name="p1">控制点1</param>
    /// <param name="p2">控制点2</param>
    /// <param name="p3">尾点</param>
    /// <returns></returns>
    private static Vector3 CalculateThreePowerBezierPoint(float t, Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3)
    {
        float u = 1 - t;
        float tt = t * t;
        float uu = u * u;
        float ttt = tt * t;
        float uuu = uu * u;

        Vector3 p = uuu * p0;
        p += 3 * t * uu * p1;
        p += 3 * tt * u * p2;
        p += ttt * p3;

        return p;
    }


    /// <summary>
    /// 获取存储贝塞尔曲线点的数组
    /// </summary>
    /// <param name="startPoint"></param>起始点
    /// <param name="controlPoint"></param>控制点
    /// <param name="endPoint"></param>目标点
    /// <param name="segmentNum"></param>采样点的数量
    /// <returns></returns>存储贝塞尔曲线点的数组
    public static Vector3[] GetLineBeizerList(Vector3 startPoint,  Vector3 endPoint, int segmentNum)
    {
        Vector3[] path = new Vector3[segmentNum];
        for (int i = 1; i <= segmentNum; i++)
        {
            float t = i / (float)segmentNum;
            Vector3 pixel = CalculateLineBezierPoint(t, startPoint, endPoint);
            path[i - 1] = pixel;
            Debug.Log(path[i - 1]);
        }
        return path;

    }

    /// <summary>
    /// 获取存储的二次贝塞尔曲线点的数组
    /// </summary>
    /// <param name="startPoint"></param>起始点
    /// <param name="controlPoint"></param>控制点
    /// <param name="endPoint"></param>目标点
    /// <param name="segmentNum"></param>采样点的数量
    /// <returns></returns>存储贝塞尔曲线点的数组
    public static Vector3[] GetCubicBeizerList(Vector3 startPoint, Vector3 controlPoint, Vector3 endPoint, int segmentNum)
    {
        Vector3[] path = new Vector3[segmentNum];
        for (int i = 1; i <= segmentNum; i++)
        {
            float t = i / (float)segmentNum;
            Vector3 pixel = CalculateCubicBezierPoint(t, startPoint,
                controlPoint, endPoint);
            path[i - 1] = pixel;
            Debug.Log(path[i - 1]);
        }
        return path;

    }

    /// <summary>
    /// 获取存储的三次贝塞尔曲线点的数组
    /// </summary>
    /// <param name="startPoint"></param>起始点
    /// <param name="controlPoint1"></param>控制点1
    /// <param name="controlPoint2"></param>控制点2
    /// <param name="endPoint"></param>目标点
    /// <param name="segmentNum"></param>采样点的数量
    /// <returns></returns>存储贝塞尔曲线点的数组
    public static Vector3[] GetThreePowerBeizerList(Vector3 startPoint, Vector3 controlPoint1, Vector3 controlPoint2 , Vector3 endPoint, int segmentNum)
    {
        Vector3[] path = new Vector3[segmentNum];
        for (int i = 1; i <= segmentNum; i++)
        {
            float t = i / (float)segmentNum;
            Vector3 pixel = CalculateThreePowerBezierPoint(t, startPoint,
                controlPoint1, controlPoint2, endPoint);
            path[i - 1] = pixel;
            Debug.Log(path[i - 1]);
        }
        return path;

    }
}

 

  • 11
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
Unity贝塞尔曲线是通过贝塞尔曲线的数学原理在Unity游戏引擎中实现的一种曲线效果。在Unity中,贝塞尔曲线可以用来创建平滑的曲线路径,并用于生成动画效果、粒子效果等。在Unity中,常用的贝塞尔曲线有一阶贝塞尔曲线、二阶贝塞尔曲线和三阶贝塞尔曲线。 一阶贝塞尔曲线是一条线性函数,通过两个控制点来定义一条直线段。二阶贝塞尔曲线是由两个一阶贝塞尔曲线的线性插值得到的,它通过三个控制点来定义一条平滑的曲线。而三阶贝塞尔曲线则是由两个二阶贝塞尔曲线的线性插值得到的,它通过四个控制点来定义一条更加复杂的曲线。 在Unity中,我们可以通过编写C#代码来实现贝塞尔曲线的计算和绘制。使用LineRenderer组件可以绘制贝塞尔曲线的路径,可以通过调整控制点的位置来改变曲线的形状。同时,我们还可以使用鼠标交互来控制曲线的控制点,实现动态的曲线效果。 总之,Unity贝塞尔曲线是一种通过数学计算和绘制技术实现的曲线效果,它可以用于游戏开发中的动画、粒子效果等场景。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [【游戏开发进阶】玩转贝塞尔曲线,教你在Unity中画Bezier贝塞尔曲线(二阶、三阶),手把手教你推导公式](https://blog.csdn.net/linxinfa/article/details/116808549)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [Unity 工具类贝塞尔 Bezier 曲线](https://blog.csdn.net/u014361280/article/details/103871840)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

仙魁XAN

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值