Unity笔记-贝塞尔曲线

定义

贝塞尔曲线(Bezier curve),又称贝兹曲线贝济埃曲线,是应用于二维图形应用程序的数学曲线。一般的矢量图形软件通过它来精确画出曲线,贝兹曲线由线段节点组成,节点是可拖动的支点,线段像可伸缩的皮筋。

首先是一阶贝塞尔曲线公式,如下:

B(t)=P0​+(P1​−P0​)t=(1−t)P0​+tP1​, t∈[0,1]

二阶公式

B(t)=(1−t)2P0​+2t(1−t)P1​+t2P2​, t∈[0,1]

三阶公式

B(t)=(1−t)3P0​+3t(1−t)2P1​+3t2(1−t)P2​+t3P3​, t∈[0,1]

实现

推导细节的话网上有很多详细的教程,这里只作应用

首先我们来看二阶公式,B(t)=(1−t)2P0​+2t(1−t)P1​+t2P2​, t∈[0,1]

假如我们在untiy中想得出一个曲线应该怎么做?

这里我们可以尝试一下

首先最基础的我们应该获得两个坐标点,分别是起点坐标和终点坐标,其次,我们通过调节t的值获得对应的曲线坐标

对应二阶三阶公式代码



public static class BezierTool
{
	public static Vector3 GetBezier(Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3, float t)
	{
		Mathf.Clamp(t, 0, 1);
		float x1 = (1 - t) * (1 - t) * (1 - t);
		float x2 = 3 * t * (1 - t) * (1 - t);
		float x3 = 3 * t * t * (1 - t);
		float x4 = t * t * t;
		return p0 * x1 + p1 * x2 + p2 * x3 + p3 * x4;
	}

	/// <summary>
	/// 起点,中间点,终点
	/// </summary>
	/// <param name="p0">起点</param>
	/// <param name="p1">中间点</param>
	/// <param name="p2">终点</param>
	/// <param name="t"></param>
	/// <returns></returns>
	public static Vector3 GetBezier(Vector3 p0, Vector3 p1, Vector3 p2, float t)
	{
		float x1 = (1 - t) * (1 - t);
		float x2 = 2 * t * (1 - t);
		float x3 = t * t;
		return p0 * x1 + p1 * x2 + p2 * x3;
	}
}

测试运行代码

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




public class BezierMove : MonoBehaviour
{
	public Transform originPoint;
	public Transform destinationPoint;
	public Transform controlPoint;
	float rate;
	public float bezierNumber;
	List<Vector3> path;
	int index;
	public float speed = 5;
	public bool isStart = false;
	private void Start()
	{
		path = new List<Vector3>();
		for (var i = 1; i < bezierNumber; i++)
		{
			float temp = 1 / bezierNumber;
			rate += temp;
			rate = Mathf.Clamp(rate, 0, 1f);
			Vector3 pathPoint = BezierTool.GetBezier(originPoint.position, controlPoint.position, destinationPoint.position, rate);
			path.Add(pathPoint);

		}
		foreach (var item in path)
		{
			print(item);
		}
		index = 0;
	}
	private void Update()
	{
		if (!isStart)
		{
			return;
		}
		
		if (index < path.Count)
		{
			transform.position = Vector3.MoveTowards(transform.position, path[index], Time.deltaTime * speed);
			if (Vector3.Distance(transform.position, path[index]) <= 0.1f)
			{
				index++;
			}
		}
	}

}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值