首页 > 其他分享 >一个贝塞尔曲线编辑工具(2d)

一个贝塞尔曲线编辑工具(2d)

时间:2024-07-28 23:51:00浏览次数:15  
标签:Count mainPoints Vector3 曲线 贝塞尔 transform 2d go public

曲线在unity下如何绘制?

类似绘制圆,是用一段一段的线段拼接来模拟的,这边也是类似,可以用一段一段的线段来模拟曲线。

 

既然要模拟,那我们也得知道贝塞尔曲线的公式才行。

一般用的比较多的就是3次贝塞尔曲线,该曲线由起点p1,p1的控制点c1,终点p2,p2的控制点c2组成。

公式为:p = p1*(1-t)+ 3*c1*t*(1-t)+ 3*c2*t2*(1-t) + p2*t3,t的范围[0, 1]

 

下面是unity下的一个贝塞尔编辑工具

 

public class MyBezierPath2dEdit : MonoBehaviour
{

    public string m_ControlInObjectName = "In"; //作为曲线结束时, c2控制点
    public string m_ControlOutObjectName = "Out"; //作为曲线启示点时, c1控制点
    public Color m_ControlInColor = Color.red; //c2控制点连线颜色
    public Color m_ControlOutColor = Color.blue; //c1点连线颜色

    public Color m_PathColor = Color.yellow; //路径绘制颜色

    [Range(1, 60)]
    public int m_Steps = 30; //曲线用多少个直线来模拟
    public bool m_LoopPath = false; //曲线是否首尾连接

    private void OnDrawGizmos()
    {
        var mainPoints = new List<Vector2>();
        var In = new List<Vector2>();
        var Out = new List<Vector2>();
        bool isAddRectTransform = null != GetComponent<RectTransform>();

        foreach (Transform child in transform)
        {
            mainPoints.Add(child.transform.position);
            foreach (Transform child2 in child.transform)
            {
                if (child2.name == m_ControlInObjectName)
                    In.Add(child2.transform.position);
                if (child2.name == m_ControlOutObjectName)
                    Out.Add(child2.transform.position);
            }

            //如果没有定义的点,则补充上去
            if (In.Count < mainPoints.Count)
            {
                GameObject go = new GameObject(m_ControlInObjectName);
                if (isAddRectTransform)
                    go.AddComponent<RectTransform>();
                go.transform.SetParent(child.transform, false);
                In.Add(go.transform.position);
            }
            if (Out.Count < mainPoints.Count)
            {
                GameObject go = new GameObject(m_ControlOutObjectName);
                if (isAddRectTransform)
                    go.AddComponent<RectTransform>();
                go.transform.SetParent(child.transform, false);
                Out.Add(go.transform.position);
            }
        }

        //曲线控制线
        for (int i = 0; i < mainPoints.Count; i++)
        {
            Gizmos.color = m_ControlInColor;
            Gizmos.DrawLine(mainPoints[i], In[i]);
            Gizmos.color = m_ControlOutColor;
            Gizmos.DrawLine(mainPoints[i], Out[i]);
        }

        Gizmos.color = m_PathColor;
        if (In.Count >= mainPoints.Count && Out.Count >= mainPoints.Count)
        {
            int mainPtCnt = mainPoints.Count;
            if (!m_LoopPath) mainPtCnt--;
            for (int i = 0; i < mainPtCnt; i++)
            {
                int i2 = (i + 1) % mainPoints.Count;
                Vector3 P2 = new Vector3(0, 0, 0);
                float step = 1.0f / m_Steps;
                if (step > 0.01f)
                {
                    for (float t = 0; t < 1 + step; t += step)
                    {
                        Vector3 P1 = P2;
                        P2 = CalcBezierPathPoint(mainPoints[i], Out[i], In[i2], mainPoints[i2], t);
                        if (t > 0)
                        {
                            Gizmos.DrawLine(P1, P2);
                        }
                    }
                }
            }
        }
    }

    private Vector3 CalcBezierPathPoint(Vector3 P0, Vector3 C0, Vector3 C1, Vector3 P1, float t)
    {
        float temp = 1 - t;
        Vector2 result = temp * temp * temp * P0 + 3 * temp * temp * t * C0 + 3 * temp * t * t * C1 + t * t * t * P1;
        return result;
    }

}

 

标签:Count,mainPoints,Vector3,曲线,贝塞尔,transform,2d,go,public
From: https://www.cnblogs.com/sailJs/p/18328984

相关文章

  • CF292D 题解
    \(O(mk\alpha(n))\)暴力,考虑对于每个询问\(l,r\),枚举\(1\siml-1,r+1\simm\),并查集连边即可。1154ms。\(O(n(m+k\alpha(n)))\)我们发现枚举\(i\in[1,l),j\in(r,m]\)太慢了。考虑先预处理出并查集从\(1\)连边到编号为\(id\)的边的状态\(pre_{id}\),倒过来再处理出......
  • 3次样条轨迹曲线算法推导(博途SCL完整源代码)
    理解3次样条插值之前,大家需要先理解3次多项式轨迹,3次多项式轨迹介绍请参考下面文章链接:3次多项式轨迹规划(PLCSCL代码)_plc按照时间轨迹规划-CSDN博客文章浏览阅读741次。机器人、运动控制等常用的轨迹规划有三次多项式、五次多项式、梯形速度规划,S型速度规划,今天我们主要介......
  • stable diffusion中的UNet2DConditionModel代码解读
    UNet2DConditionModel总体结构图片来自于https://zhuanlan.zhihu.com/p/635204519stablediffusion运行unet部分的代码。noise_pred=self.unet(sample=latent_model_input,#(2,4,64,64)生成的latenttimestep=t,#时刻tencoder_hidden_states=pro......
  • Matlab编程资源库(9)数据插值与曲线拟合
    一、一维数据插值    在MATLAB中,实现这些插值的函数是interp1,其调用格式为:Y1=interp1(X,Y,X1,'method')    函数根据X,Y的值,计算函数在X1处的值。X,Y是两个等长的已知向量,分别描述采样点和样本值,X1是一个向量或标量,描述欲插值的点,Y1是一个与X1等长的插值结......
  • 【参数化建模】利用Python在Abaqus里面绘制复杂曲线——以“爱心曲线”为例
    【参数化建模】利用Python在Abaqus里面绘制复杂曲线——以“爱心曲线”为例说在前面Python在Abaqus里面可以批量处理很多事情,包括复杂曲线的绘制,这里以心形线为例。心形线函数这里我们选取一款比较经典的心形线:Abaqus代码#--coding:utf-8--importnumpyasnpfr......
  • 【MATLAB源码-第159期】基于matlab的胡桃夹子优化算法(NOA)机器人栅格路径规划,输出做短
    操作环境:MATLAB2022a1、算法描述胡桃夹子优化算法(NutcrackerOptimizationAlgorithm,NOA)是一个灵感来源于胡桃夹子的故事的元启发式优化算法。这个故事中,胡桃夹子是一个能够将坚果壳轻易地破开以获取内部果仁的工具。在优化算法的语境下,这个过程被比喻为寻找问题解决方案......
  • LayaAir3.x 物理2D碰撞事件
    const{regClass,property}=Laya;@regClass()exportclassPlayerBulletextendsLaya.Script{declareowner:Laya.Sprite;private_body:Laya.RigidBody;onAwake():void{this._body=this.owner.getComponent(Laya.RigidBody);......
  • 像素值与 2D NPS 的标准差 - NPS 的总和还是平均值?
    我正在尝试根据Python中的2DNPS估计空间域中像素值的SD。我希望需要NPS值的总和除以像素总数。然而,我只能通过平均值除以像素总数来达到正确的估计。任何人都可以指出我为什么会这样吗?请参阅下面的代码示例。“SUM:“importnumpyasnpfromscipy.ff......
  • 【unity实战】完美的2D横版平台跳跃玩家控制器,使用InputSystem+有限状态机实现人物加
    最终效果文章目录最终效果前言素材目录结构动画配置检测脚本状态机玩家有限状态机玩家控制脚本定义人物不同状态待机移动跳跃下落状态落地状态墙壁滑行状态蹬墙跳状态蹬墙跳下落状态一段近战攻击状态二段近战攻击状态冲锋状态土狼时间状态攀爬开始状态攀爬进行状态功能......
  • 给园子的会员送送优惠,和你的数据库聊聊天:会员权益「Chat2DB 特惠」上线
    在园子遇到紧急困难发出求救信后,很多园友纷纷出手购买会员相救,非常感谢大家的支持!但目前会员权益很少,而我们的开发人手极其有限,为了增加更多会员权益,我们想到一个暂时的偷懒方法,尝试找优秀的厂商合作,给园子的会员特别的优惠。但这个偷懒想法并不容易实现,优秀的厂商不一定愿意理......