C#代码实现贝塞尔曲线(二阶/三阶)

 物体类似曲线或波浪线等效果的移动可以直接使用

/// <summary>
    /// 贝塞尔曲线移动
    /// </summary>
    public class BezierCurveMove
    {
        public BezierCurveMove(Transform obj, Vector3 startPos, Vector3 endPos, float moveTime, Vector3 control1Pos)
        {
            _moveObject = obj;
            _startPos = startPos;
            _endPos = endPos;
            _moveTime = moveTime;
            _control1Pos = control1Pos;
            _control2Pos = Vector3.zero;
        }
        public BezierCurveMove(Transform obj, Vector3 startPos, Vector3 endPos, float moveTime, Vector3 control1Pos, Vector3 control2Pos)
        {
            _moveObject = obj;
            _startPos = startPos;
            _endPos = endPos;
            _moveTime = moveTime;
            _control1Pos = control1Pos;
            _control2Pos = control2Pos;
        }

        private Transform _moveObject;
        // 物体移动的时间
        private float _moveTime = 1f;
        // 控制位置1
        private Vector3 _control1Pos;
        // 控制位置2
        private Vector3 _control2Pos;
        // 起始位置
        private Vector3 _startPos;
        // 结束位置
        private Vector3 _endPos;

        // 记录物体开始移动的时间
        private float _startTime;

        // 当前状态
        private bool _isMove;

        public bool IsMove()
        {
            return _isMove;
        }
        // 回调(用于移动结束后执行)
        Action _callBack = null;
        public void Start(Action callBack = null)
        {
            // 记录回调
            _callBack = callBack;

            // 将状态改为开始移动
            _isMove = true;

            // 记录物体开始移动的时间
            _startTime = Time.time;

            // 启动协程,移动物体
            BezierCurveMoveHelper.Instance.StartCoroutine(Move());
        }

        private IEnumerator Move()
        {
            // 规定时间内可移动
            while (Time.time <= _startTime + _moveTime)
            {
                // 计算当前时间点在曲线上的位置
                float t = (Time.time - _startTime) / _moveTime;

                // 使用贝塞尔曲线计算物体的位置
                Vector3 newPos = Vector3.zero;
                if (_control2Pos == Vector3.zero)
                {
                    newPos = CalculateBezierPoint(t, _startPos, _control1Pos, _endPos);
                }
                else
                {
                    newPos = CalculateBezierPoint(t, _startPos, _control1Pos, _control2Pos, _endPos);
                }


                // 更新物体的位置
                _moveObject.position = newPos;

                // 暂停一帧,继续执行下一帧
                yield return new WaitForEndOfFrame();
            }

            // 移动结束后,将物体移动到目标位置
            _moveObject.position = _endPos;

            // 将状态改为结束移动
            _isMove = false;

            // 判断回调不为空执行回调
            if (_callBack != null)
            {
                _callBack();
                _callBack = null;
            }

        }

        // 根据贝塞尔曲线公式计算曲线上的点
        private Vector3 CalculateBezierPoint(float t, Vector3 startPoint, Vector3 controlPoint, Vector3 endPoint)
        {
            //二阶公式:1-t^2 * P0 +
            //2t * 1-t * P1 +
            //t^2 * P2

            float u = 1 - t;
            float tt = t * t;
            float uu = u * u;

            Vector3 point =
                uu * startPoint +
                2 * u * t * controlPoint +
                tt * endPoint;
            return point;
        }

        private Vector3 CalculateBezierPoint(float t, Vector3 startPoint, Vector3 control1Point, Vector3 control2Point, Vector3 endPoint)
        {
            //三阶公式:(1-t)^3 * P0 +
            //3t * (1-t)^2 * P1 +
            //3 * 1-t * t^2 * P2 +
            //t^3 * P3

            float u = 1 - t;
            float tt = t * t;
            float uu = u * u;
            float uuu = uu * u;
            float ttt = tt * t;

            Vector3 point =
                uuu * startPoint +
                3 * uu * t * control1Point +
                3 * u * tt * control2Point +
                ttt * endPoint;

            return point;
        }

    }

    public class BezierCurveMoveHelper : MonoBehaviour
    {
        private static BezierCurveMoveHelper _instance = null;
        private static readonly object locker = new object();
        public static BezierCurveMoveHelper Instance
        {
            get
            {
                if (_instance == null)
                {
                    lock (locker)
                    {
                        if (_instance == null)
                        {
                            _instance = new BezierCurveMoveHelper();
                        }
                    }
                }
                return _instance;
            }
        }
    }

使用方法:

  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是一个简单的三阶贝塞尔曲线C# 代码示例: ```csharp using System; using System.Drawing; using System.Windows.Forms; public class BezierCurveForm : Form { private Point[] controlPoints; public BezierCurveForm() { controlPoints = new Point[4]; controlPoints[0] = new Point(50, 100); controlPoints[1] = new Point(150, 50); controlPoints[2] = new Point(250, 150); controlPoints[3] = new Point(350, 100); this.ClientSize = new Size(400, 200); this.Paint += new PaintEventHandler(BezierCurveForm_Paint); } private void BezierCurveForm_Paint(object sender, PaintEventArgs e) { Graphics g = e.Graphics; Pen pen = new Pen(Color.Black, 2); // 绘制控制点 for (int i = 0; i < controlPoints.Length; i++) { g.FillEllipse(Brushes.Red, controlPoints[i].X - 3, controlPoints[i].Y - 3, 6, 6); } // 绘制贝塞尔曲线 for (double t = 0; t <= 1; t += 0.01) { Point p = CalculateBezierPoint(t, controlPoints); g.FillEllipse(Brushes.Blue, p.X - 1, p.Y - 1, 2, 2); } // 绘制控制线 g.DrawLine(pen, controlPoints[0], controlPoints[1]); g.DrawLine(pen, controlPoints[1], controlPoints[2]); g.DrawLine(pen, controlPoints[2], controlPoints[3]); } private Point CalculateBezierPoint(double t, Point[] controlPoints) { double u = 1 - t; double tt = t * t; double uu = u * u; double uuu = uu * u; double ttt = tt * t; double x = uuu * controlPoints[0].X; // (1-t)^3 * P0 x += 3 * uu * t * controlPoints[1].X; // 3 * (1-t)^2 * t * P1 x += 3 * u * tt * controlPoints[2].X; // 3 * (1-t) * t^2 * P2 x += ttt * controlPoints[3].X; // t^3 * P3 double y = uuu * controlPoints[0].Y; // (1-t)^3 * P0 y += 3 * uu * t * controlPoints[1].Y; // 3 * (1-t)^2 * t * P1 y += 3 * u * tt * controlPoints[2].Y; // 3 * (1-t) * t^2 * P2 y += ttt * controlPoints[3].Y; // t^3 * P3 return new Point((int)Math.Round(x), (int)Math.Round(y)); } public static void Main() { Application.Run(new BezierCurveForm()); } } ``` 这段代码创建了一个简单的窗体应用程序,绘制了一个三阶贝塞尔曲线,并显示了控制点和控制线。你可以根据需要修改控制点的坐标,以获得不同形状的贝塞尔曲线。运行程序后,你会看到绘制的贝塞尔曲线在窗体中显示出来。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值