游戏编程精粹学习 - CatmullRom路径/线段平滑

来自《游戏编程精粹1》寻路部分文章,使用CatmullRom插值来达到平滑,算是对书中内容的练习。

 

 

复制代码
using UnityEngine;
using System.Collections;

public class Practice : MonoBehaviour
{
    public Transform[] points;


    void OnDrawGizmos()
    {
        //DrawSegmentPath();
        DrawSmoothPath();
    }

    void DrawSegmentPath()
    {
        for (int i = 1, j = 0; i < points.Length; i++, j++)
        {
            var a = points[i];
            var b = points[j];

            Gizmos.DrawLine(a.position, b.position);
        }
    }

    void DrawSmoothPath()
    {
        for (int i = 3; i < points.Length; i++)
        {
            var a = points[i - 3];
            var b = points[i - 2];
            var c = points[i - 1];
            var d = points[i];

            DrawCurve(a.position, b.position, c.position, d.position);
        }

        var fixA = points[0];
        var fixB = points[1];
        var fixC = points[2];
        var diff = fixB.position - fixA.position;
        var fill = fixA.position + diff.normalized * diff.magnitude;
        DrawCurve(fill, fixA.position, fixB.position, fixC.position);

        fixA = points[points.Length - 3];
        fixB = points[points.Length - 2];
        fixC = points[points.Length - 1];
        diff = fixC.position - fixB.position;
        fill = fixC.position + diff.normalized * diff.magnitude;
        DrawCurve(fixA.position, fixB.position, fixC.position, fill);
    }

    void DrawCurve(Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3)
    {
        for (float i = 1, j = 0, iMax = 20f; i <= iMax; i++, j++)
        {
            var t1 = i / iMax;
            var t2 = j / iMax;

            var tempP0 = CatmullRom(p0, p1, p2, p3, t1);
            var tempP1 = CatmullRom(p0, p1, p2, p3, t2);

            Gizmos.DrawLine(tempP0, tempP1);
        }
    }

    Vector3 CatmullRom(Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3, float u)
    {
        var r = p0 * (-0.5f * u * u * u + u * u - 0.5f * u) +
                p1 * (1.5f * u * u * u + -2.5f * u * u + 1f) +
                p2 * (-1.5f * u * u * u + 2f * u * u + 0.5f * u) +
                p3 * (0.5f * u * u * u - 0.5f * u * u);

        return r;
    }
}
复制代码

 

posted @   HONT  阅读(1038)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
历史上的今天:
2014-09-02 C#用正则表达式一键Unicode转UTF8(解决LitJson中文问题)
点击右上角即可分享
微信分享提示
回到顶部