首页 > 其他分享 >Unity中的数学基础——贝塞尔曲线

Unity中的数学基础——贝塞尔曲线

时间:2023-10-16 15:32:34浏览次数:29  
标签:P0 P1 float 曲线 贝塞尔 Unity Vector3


一:前言 

一条贝塞尔曲线是由一组定义的控制点P0到 Pn,n=1为线性,n=2为二次......第一个和最后一个控制点称为起点和终点,中间的控制点一般不会位于曲线上 
获取两个点之间的点就是通过线性插值( Mathf.Lerp),0 <= t <= 1


二:贝塞尔曲线公式

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

Unity中的数学基础——贝塞尔曲线_贝塞尔曲线


Unity中的数学基础——贝塞尔曲线_unity_02

——二阶贝塞尔曲线:二次方贝塞尔曲线的路径由给定点P0、P1、P2的函数B(t)公式推导:由(P0,P1),(P1,P2)分别求线性公式所得的结果P0‘ 和 P1‘再带入线性公式,整理所得即为二次公式

P0,P1所求:

Unity中的数学基础——贝塞尔曲线_游戏引擎_03


P1,P2所求:

Unity中的数学基础——贝塞尔曲线_unity_04


P0,P1,P2二次方公式:

Unity中的数学基础——贝塞尔曲线_游戏引擎_05


简化所得

Unity中的数学基础——贝塞尔曲线_贝塞尔曲线_06


Unity中的数学基础——贝塞尔曲线_贝塞尔曲线_07

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

其公式为

Unity中的数学基础——贝塞尔曲线_游戏引擎_08

 

Unity中的数学基础——贝塞尔曲线_List_09


三:公式转换为代码

using UnityEngine;

/// <summary>
/// 贝塞尔工具类
/// </summary>
public static class BezierUtils
{
    /// <summary>
    /// 线性贝塞尔曲线
    /// </summary>
    public static Vector3 BezierCurve(Vector3 p0, Vector3 p1, float t)
    {
        Vector3 B = Vector3.zero;
        B = (1 - t) * p0 + t * p1;
        return B;
    }

    /// <summary>
    /// 二阶贝塞尔曲线
    /// </summary>
    public static Vector3 BezierCurve(Vector3 p0, Vector3 p1, Vector3 p2, float t)
    {
        Vector3 B = Vector3.zero;
        float t1 = (1 - t) * (1 - t);
        float t2 = 2 * t * (1 - t);
        float t3 = t * t;
        B = t1 * p0 + t2 * p1 + t3 * p2;
        return B;
    }

    /// <summary>
    /// 三阶贝塞尔曲线
    /// </summary>
    public static Vector3 BezierCurve(Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3, float t)
    {
        Vector3 B = Vector3.zero;
        float t1 = (1 - t) * (1 - t) * (1 - t);
        float t2 = 3 * t * (1 - t) * (1 - t);
        float t3 = 3 * t * t * (1 - t);
        float t4 = t * t * t;
        B = t1 * p0 + t2 * p1 + t3 * p2 + t4 * p3;
        return B;
    }
}

 四:绘制出曲线

  

Unity中的数学基础——贝塞尔曲线_贝塞尔曲线_10

using System.Collections.Generic;
using UnityEngine;

public class BezierTest : MonoBehaviour
{
    public int m_CurveDensity;//曲线密度
    public bool m_IsSecondOrderBezier;//是否为二阶贝塞尔曲线,否则为三阶贝塞尔曲线

    private List<Transform> m_ControlPointList = new List<Transform>();//所有的控制点(控制点作为挂载此脚本的游戏物体的子物体)

    public void OnDrawGizmos()
    {
        //添加控制点
        m_ControlPointList.Clear();
        foreach (Transform trans in transform)
        {
            m_ControlPointList.Add(trans);
        }

        List<Vector3> pointList = new List<Vector3>();//曲线上的所有点
        if (m_IsSecondOrderBezier)
        {
            if (m_ControlPointList.Count < 3)
            {
                return;
            }
            //获取曲线上的所有点
            for (int i = 0; i < m_ControlPointList.Count - 2; i += 2)
            {
                Vector3 p0 = m_ControlPointList[i].position;
                Vector3 p1 = m_ControlPointList[i + 1].position;
                Vector3 p2 = m_ControlPointList[i + 2].position;
                for (int j = 0; j <= m_CurveDensity; j++)
                {
                    float t = j * 1f / m_CurveDensity;
                    Vector3 point = BezierUtils.BezierCurve(p0, p1, p2, t);
                    pointList.Add(point);
                }
            }
        }
        else
        {
            if (m_ControlPointList.Count < 4)
            {
                return;
            }
            //获取曲线上的所有点
            for (int i = 0; i < m_ControlPointList.Count - 3; i += 3)
            {
                Vector3 p0 = m_ControlPointList[i].position;
                Vector3 p1 = m_ControlPointList[i + 1].position;
                Vector3 p2 = m_ControlPointList[i + 2].position;
                Vector3 p3 = m_ControlPointList[i + 3].position;
                for (int j = 0; j <= m_CurveDensity; j++)
                {
                    float t = j * 1f / m_CurveDensity;
                    Vector3 point = BezierUtils.BezierCurve(p0, p1, p2, p3, t);
                    pointList.Add(point);
                }
            }
        }

        //绘制所有点
        foreach (var point in pointList)
        {
            Gizmos.DrawSphere(point, 0.1f);
        }
        //绘制控制点连线
        Gizmos.color = Color.red;
        for (int i = 0; i < m_ControlPointList.Count - 1; i++)
        {
            Gizmos.DrawLine(m_ControlPointList[i].position, m_ControlPointList[i + 1].position);
        }
    }
}

标签:P0,P1,float,曲线,贝塞尔,Unity,Vector3
From: https://blog.51cto.com/u_15296378/7884455

相关文章

  • CItect2018 R2过程分析器显示不了曲线
    这一篇博客我在新浪博客记录过,在这里也记录一遍,新浪博客地址是CItect2018R2过程分析器显示不了曲线_来自金沙江的小鱼_新浪博客(sina.com.cn)这两天在现场遇到奇怪的现象,CITECT2018R2的过程分析器显示不了曲线,如果在线运行时在过程分析器添加一个趋势笔,那么所有曲线就能立马显示......
  • WINCCV7.5SP2VBS+复选框做趋势曲线显示隐藏功能
    这是我在新浪博客发表过的一篇学习笔记,在这里也记录一遍。新浪博客地址是WINCCV7.5SP2VBS+复选框做趋势曲线显示隐藏功能_来自金沙江的小鱼_新浪博客(sina.com.cn) 新建一个WINCC项目,新建3个内u浮点数变量,2个BOOL变量,设置初始值。设置变量记录,关联这5个变量,启动变量记录。新建......
  • 使用Git管理Unity项目
    使用Git管理Unity项目目录前置准备注册GitHub账号下载安装Git,进行基础的配置将自己的项目传到GITHUB前置准备注册GitHub账号前往GitHub官网注册一个自己的账号,注意要开梯子进去。这些就不多说了下载安装Git,进行基础的配置1.前往Git官网下载安装git,安装期间有许多选项,可以直......
  • 【Unity3D】花瓣特效
    1花瓣绘制原理​如下图是实现的花瓣特效效果,为方便描述,我们将每个红色的扁状长条称为花瓣,每个花瓣中心的绿点称为花蕊,花朵的正中心称为花心。​我们在xOz平面上绘制花朵,假设花心为O点,其世界坐标为_Center,花瓣个数为_PetalNum,花瓣半长度和半宽度分别为_PetalLe......
  • 【Unity3D】消融特效
    1前言​选中物体消融特效中基于Shader实现了消融特效,本文将基于ShaderGraph实现消融特效,两者原理一样,只是表达方式不同,另外,选中物体消融特效中通过discard丢弃片元,本文通过alpha测试丢弃片元。​ShaderGraph环境搭建、简单应用详见→ShaderGraph简介。​......
  • 【Unity3D】Shader Graph简介
    1ShaderGraph简介​ShaderGraph是Unity官方在2018年推出的Shader制作插件,是图形化的Shader制作工具,类似于Blender中的ShaderEditor和UE中的MaterialEditor,它使用流程图的形式表达顶点变换和片元着色的流程,通过节点(Node)的连接实现各种复杂的特效,关于节......
  • 循序渐进介绍基于CommunityToolkit.Mvvm 和HandyControl的WPF应用端开发(8) -- 使用Co
    在我们WPF应用端的时候,和WInform开发或者Vue前端开发一样,有时候也需要对内容进行转义处理,如把一些0,1数值转换为具体含义的文本信息,或者把一些布尔变量转换为是否等,都是常见的转换处理,本篇随笔介绍在WPF应用端对内容使用Converter类实现内容的转义处理的操作。1、使用Converter实......
  • 循序渐进介绍基于CommunityToolkit.Mvvm 和HandyControl的WPF应用端开发(7) -- 图标列
    我们在WPF应用端的界面中,使用lepoco/wpfui来做主要的入口框架,这个项目它的菜单内置了不少图标,我们需要在动态菜单的配置中,使用它作为图标的展示处理,本篇随笔介绍如何基于图标枚举集合进行图标的展示和选择处理。并扩展到Font-Awesome-WPF的处理进行展示和选择。1、lepoco/wpfui......
  • Unity完美像素Sprite:怎么让图片变得清晰(转载) Unity Pixel Perfect Sprite: How To Ach
    https://gamedevelopertips.com/unity-pixel-perfect-sprite/SoIwasmakingalittleprototypeformynewgamewhenIjustcameacrossalittleproblem.ThespritethatIwasloadingintoUnitywasjustlookingtoopixelatedandnotsharpatall.SoIspen......
  • 问题记录:Unity部分Sprite跳跃移动
    问题展示这个图片中,可以发现巴郡两个字的移动和其他图片不一致。表面原因是因为这个两个图片资产的filtermode为point导致的,其他图片资产为bilinear。解决方案未知。......