zoukankan      html  css  js  c++  java
  • Beizer 贝塞尔曲线移动

    又到了开学的时候了~  开学第一课 使用贝塞尔曲线绘制路径并移动 吼吼

    这部分是摘录

    Bézier curve(贝塞尔曲线)是应用于二维图形应用程序的数学曲线。 曲线定义:起始点、终止点(也称锚点)、控制点。通过调整控制点,贝塞尔曲线的形状会发生变化。 1962年,法国数学家Pierre Bézier第一个研究了这种矢量绘制曲线的方法,并给出了详细的计算公式,因此按照这样的公式绘制出来的曲线就用他的姓氏来命名,称为贝塞尔曲线。

    以下公式中:B(t)为t时间下 点的坐标;

    P0为起点,Pn为终点,Pi为控制点

    一阶贝塞尔曲线(线段):

    82984310y353

    82984413d5g2

    意义:由 P0 至 P1 的连续点, 描述的一条线段

    二阶贝塞尔曲线(抛物线):

    82984320aws6

    82984428gq1x

    原理:由 P0 至 P1 的连续点 Q0,描述一条线段。
          由 P1 至 P2 的连续点 Q1,描述一条线段。
          由 Q0 至 Q1 的连续点 B(t),描述一条二次贝塞尔曲线。

    经验:P1-P0为曲线在P0处的切线。

    三阶贝塞尔曲线:

    82984326c3m1

    82984443k2nb

    通用公式:

    82984842izn0

    高阶贝塞尔曲线:

    4阶曲线:

    82984909h1a9

    5阶曲线:

    829849831aal

    http://www.cs.mtu.edu/~shene/COURSES/cs3621/NOTES/spline/Bezier/de-casteljau.html

    下面是试用贝塞尔曲线来设置路径 然后使自身按照曲线移动,代码来源 A Pathfinding Project 插件Demo ,写的不错 先收藏了,比较重要的是Plot函数用来计算曲线

    using UnityEngine;
    using System.Collections;
    using Pathfinding;
    
    public class BezierMover : MonoBehaviour {
    
        public Transform[] points;
    
        public float tangentLengths = 5;
        public float speed = 1;
    
        float time = 0;
    
        void Update (  ) {
            Move ( true );
        }
    
        Vector3 Plot (float t) {
            Vector3 inTang, outTang;
            
            
            int c = points.Length;
            int pt = Mathf.FloorToInt(t);
            inTang = (  (points[(pt+1)%c].position - points[(pt+0)%c].position).normalized - (points[(pt-1+c)%c].position - points[(pt+0)%c].position).normalized ).normalized;
            
            outTang = (  (points[(pt+2)%c].position - points[(pt+1)%c].position).normalized - (points[(pt-0+c)%c].position - points[(pt+1)%c].position).normalized ).normalized;
            
            Debug.DrawLine ( points[pt%c].position, points[pt%c].position + inTang*tangentLengths, Color.red);
            Debug.DrawLine ( points[(pt+1)%c].position - outTang*tangentLengths, points[(pt+1)%c].position, Color.green);
    
            return AstarMath.CubicBezier ( points[pt%c].position, points[pt%c].position + inTang*tangentLengths, points[(pt+1)%c].position - outTang*tangentLengths, points[(pt+1)%c].position, t - pt);
        }
    
        // Update is called once per frame
        void Move ( bool progress ) {
    
            /*if ( time > pt+1 ) {
                Move ( false );
                return;
            }*/
    
            float mn = time;
            float mx = time+1;
            while ( mx - mn > 0.0001f ) {
                float mid = (mn+mx)/2;
    
                Vector3 p = Plot ( mid );
                if ( (p-transform.position).sqrMagnitude > (speed*Time.deltaTime)*(speed*Time.deltaTime) ) {
                    mx = mid;
                } else {
                    mn = mid;
                }
            }
    
            time = (mn+mx)/2;
    
    
            /*Vector3 p1 = AstarMath.CubicBezier ( points[pt%c].position, points[pt%c].position + inTang*tangentLengths, points[(pt+1)%c].position - outTang*tangentLengths, points[(pt+1)%c].position, time - pt);
            Vector3 p2 = AstarMath.CubicBezier ( points[pt%c].position, points[pt%c].position + inTang*tangentLengths, points[(pt+1)%c].position - outTang*tangentLengths, points[(pt+1)%c].position, time - pt + 0.001f);*/
            Vector3 p1 = Plot(time);
            Vector3 p2 = Plot(time+0.001f);
            transform.position = p1;
            transform.rotation = Quaternion.LookRotation ( p2 - p1 );
    
        }
    
        public void OnDrawGizmos () {
            if ( points.Length >= 3 ) {
    
                for ( int i = 0; i < points.Length; i++ ) if ( points[i] == null ) return;
    
                for ( int pt = 0; pt < points.Length; pt++ ) {
    
                    int c = points.Length;
                    Vector3 inTang = (  (points[(pt+1)%c].position - points[pt+0].position).normalized - (points[(pt-1+c)%c].position - points[pt+0].position).normalized ).normalized;
                    
                    Vector3 outTang = (  (points[(pt+2)%c].position - points[(pt+1)%c].position).normalized - (points[(pt-0+c)%c].position - points[(pt+1)%c].position).normalized ).normalized;
    
                    Vector3 pp = points[pt].position;
                    
                    for ( int i=1;i<=100;i++) {
                        Vector3 p = AstarMath.CubicBezier ( points[pt].position, points[pt].position + inTang*tangentLengths, points[(pt+1)%c].position - outTang*tangentLengths, points[(pt+1)%c].position, i / 100.0f );
                        Gizmos.DrawLine ( pp, p );
                        pp = p;
                    }
                }
    
            }
        }
    
    }
  • 相关阅读:
    SQL语句大全
    软件设计方法
    统计在线的用户
    解放web程序员的输入验证
    OUTLOOK菜单类
    在asp.net 2.0中结合母板页meta,Tiele重置
    微软自带AJAX的用法
    在asp.net 2.0中发送邮件
    js编写的语法高亮引擎
    有关模版MasterPage的问题
  • 原文地址:https://www.cnblogs.com/Keyle/p/4775864.html
Copyright © 2011-2022 走看看