贝塞尔曲线的定义我就不详细说了,网上很多资料都有介绍可以用递归方法求曲线点也可以用迭代法求解,这里使用迭代法求点,总的来说就是第一个控制点到第二个控制点的细分点和第二个到第三个控制点连成的线,其他的更高阶的以此类推,知道迭代到点的集合的长度为1,

这里采用左键单击画布就会生成一个控制点,根据控制点进行步进生成点进而绘制出来:


const {ccclass, property,requireComponent} = cc._decorator;export interface Vector2 {x: number,y: number
}@ccclass
@requireComponent(cc.Graphics)
export default class BezierTest extends cc.Component {@property(cc.Prefab)dotPrefab: cc.Prefab = null;@property(cc.Prefab)settingPrefab: cc.Prefab = null;@property(cc.Graphics)pen: cc.Graphics = null;@property(cc.Node)box: cc.Node = null;@property({type: cc.Integer,tooltip: '步进长度,帧率,控制t'})stepFrame: number = 60;/** 控制点数组 */private _controllPoints: Vector2[] = [];/** 生成的目标点信息 即贝塞尔曲线的信息 */private _targetPoints: Vector2[] = [];private _controllNodes: cc.Node[] = [];onLoad () {}protected onEnable(): void {this.node.on(cc.Node.EventType.TOUCH_END,this.tapEnd,this);cc.director.on('repaint',this.repaint,this);cc.director.on('exportData',this.exportData,this);cc.director.on('clear',this.clearAllData,this);}   protected onDisable(): void {this.node.off(cc.Node.EventType.TOUCH_END,this.tapEnd,this);cc.director.off('repaint',this.repaint,this);cc.director.off('exportData',this.exportData,this);cc.director.off('clear',this.clearAllData,this);}exportData(): void {console.log('export');if(this._targetPoints.length > 0) {this._targetPoints = this._targetPoints.map(item => ({x: item.x,y: item.y,rotate: 0}))let len = this._targetPoints.length;for(let i = 0; i < len - 1; i++) {let cur = this._targetPoints[i];let next = this._targetPoints[i + 1];let offsetY = next.y - cur.y;let offsetX = next.x - cur.x;let tanRes = offsetY / offsetX;let r = Math.atan(tanRes);let angle = 180 * r / Math.PI;// 设置经过该点的角度值cur['rotate'] = angle;}this._targetPoints[len - 1]['rotate'] = this._targetPoints[len - 2]['rotate'];console.log('targetPoint is ',this._targetPoints);const blob = new Blob([JSON.stringify(this._targetPoints)],{type: 'application/json'});const a = document.createElement('a');a.href = window.webkitURL.createObjectURL(blob);a.download = '';a.click();}}clearAllData(): void {this.pen.clear();this._controllNodes.length = 0;this._controllPoints.length = 0;}/** 重新绘制 */repaint(): void {this._controllPoints = [];this._controllNodes.forEach(item => {this._controllPoints.push(item.position);});this.checkControllPoints();}tapEnd(event: cc.Event.EventTouch) {// 生成点const localPos = this.node.convertToNodeSpaceAR(event.getLocation());if(event.target == this.node) {const dotNode = cc.instantiate(this.dotPrefab);this.node.addChild(dotNode);dotNode.setPosition(localPos);this._controllPoints.push(localPos);this._controllNodes.push(dotNode);}this.checkControllPoints();}checkControllPoints() {/** 清空路径点 */this._targetPoints = [];if(this._controllPoints.length > 1) {// 绘制for(let i = 0; i <= this.stepFrame; i++) {this.changeT(i / this.stepFrame);}console.log('targetpoints is',this._targetPoints);this.pen.clear();this.drawControllPoints();if(this._targetPoints.length > 1) {this.pen.strokeColor = cc.color().fromHEX('#ff0000');this._targetPoints.forEach((item,index) => {if(!index) {this.pen.moveTo(item.x,item.y);} else {this.pen.lineTo(item.x,item.y);}});this.pen.stroke();}}}drawControllPoints(): void {this.pen.strokeColor = cc.color().fromHEX('#dcdcdc');this._controllPoints.forEach((item,index) => {if(!index) {this.pen.moveTo(item.x,item.y);} else {this.pen.lineTo(item.x,item.y);}});this.pen.stroke();}/** 改变时间参数t 关键代码 */changeT(ratio: number): void {console.log('ratio is ',ratio);let tempPosArr: Vector2[] = [];for(let i = 0,len = this._controllPoints.length; i < len - 1; i++) {let deltaX = this._controllPoints[i + 1].x - this._controllPoints[i].x;let deltaY = this._controllPoints[i + 1].y - this._controllPoints[i].y;let x = this._controllPoints[i].x + deltaX * ratio;let y = this._controllPoints[i].y + deltaY * ratio;let targetPoint = {x,y};tempPosArr.push(targetPoint);}console.log('tempPosArr is ',tempPosArr);// 一直迭代直到tempPosArr的长度为1while(tempPosArr.length > 1) {let posArrLen = tempPosArr.length;for(let i = 0, len = tempPosArr.length; i < len - 1; i++) {let deltaX = tempPosArr[i + 1].x - tempPosArr[i].x;let deltaY = tempPosArr[i + 1].y - tempPosArr[i].y;let x = tempPosArr[i].x + deltaX * ratio;let y = tempPosArr[i].y + deltaY * ratio;let tp = {x,y};tempPosArr.push(tp);}tempPosArr.splice(0,posArrLen);}if(tempPosArr.length === 1) {this._targetPoints.push(tempPosArr[0]);}}async play() {this.box.active = true;for(let item of this._targetPoints) {this.box.setPosition(cc.v2(item.x,item.y));this.box.angle = item['rotate'];await new Promise((resolve) => {setTimeout(resolve,100);})}}settingsEvent() {const settingNode = cc.instantiate(this.settingPrefab);this.node.addChild(settingNode);}start () {}// update (dt) {}
}

导出数据的时候需要计算每个点需要旋转的角度值,这里做的比较粗略,因为曲线上的点比较密集,就粗略计算两个点之间的坐标差值求正切得到角度值,导出的时候需要用到blob对象来创建下载链接

const blob = new Blob([JSON.stringify(this._targetPoints)],{type: 'application/json'});

const a = document.createElement('a');

a.href = window.webkitURL.createObjectURL(blob);

a.download = '';

a.click();

cocos 贝塞尔曲线编辑器相关推荐

  1. Android Studio Canvas 实现鼠标贝塞尔曲线拖尾特效(富文本编辑器)

    特效预览图 什么是贝塞尔曲线? 百度百科: 贝塞尔曲线(Bézier curve),又称贝兹曲线或贝济埃曲线,是应用于二维图形应用程序的数学曲线.一般的矢量图形软件通过它来精确画出曲线,贝兹曲线由线段 ...

  2. cocos creator 3.x使用tween缓动接口和贝塞尔曲线实现简易抛物线

    抛物线还是比较常用的,人物跳跃,投掷物等等,2dx和3.x接口很多都不兼容了,本文使用3.x中的缓动函数配合onUpdate钩子,计算并设置贝塞尔曲线中的坐标实现简易的抛物线运动. 代码: nodeM ...

  3. matlab 贝塞尔曲线,matlab实现贝塞尔曲线绘图pdf查看

    贝塞尔曲线绘图方法: %Program 3.7 Freehand Draw Program Using Bezier Splines %Click in Matlab figure window to ...

  4. WPF将点列连接成光滑曲线——贝塞尔曲线

    背景 最近在写一个游戏场景编辑器,虽然很水,但是还是遇到了不少问题.连接离散个点列成为光滑曲线就是一个问题.主要是为了通过关键点产生2D的赛道场景.总之马路不可能是直线相连的,当然需要曲线光滑相连.现 ...

  5. 贝塞尔曲线轨迹运动原理与实战

    大厂技术  坚持周更  精选好文 本次分享大概分为下面几个方面 背景 贝塞尔曲线讲解 实现和探索过程 背景 近期在 X 业务测评报告页有一个需求,用户可以左右拖动滑块来查看各个等级的信息. 在之前的野 ...

  6. unity 控制点 贝塞尔曲线_在Unity中使用贝塞尔曲线(转)

    鼎鼎大名的贝塞尔曲线相信大家都耳熟能详.这两天因为工作的原因需要将贝塞尔曲线加在工程中,那么MOMO迅速的研究了一下成果就分享给大家了哦.贝塞尔曲线的原理是由两个点构成的任意角度的曲线,这两个点一个是 ...

  7. 匀速贝塞尔曲线路径规划工具

    在做游戏开发的时候经常会用到贝塞尔曲线来规划路径,在网上也没找到合适的demo,要么就是不支持高阶贝塞尔,要么就是不能匀速运动.所以决定趁着闲余时间自己写一个工具,方便以后用. 于是就有了该项目,并且 ...

  8. 3阶以下贝塞尔曲线轨迹库和任意轨迹库

    20130521:任意轨迹库中添加19条轨迹.按屏幕矩形边界上有16个点,连接起点P_i和终点P_j的轨迹平均有3条计算,任意轨迹库最多约有240*3=720条轨迹. 20130522-2013052 ...

  9. CocosCreator自制贝塞尔曲线工具

    在做游戏的时候,时常会遇到一些动画需要通过贝塞尔曲线来完成,于是打算做一个小工具便于以后快速的制作Bezier曲线 功能: 1.可视化,便于调节参数,可以在编辑器环境显示出曲线 2.易用,开箱即用,B ...

最新文章

  1. Silverlight揭秘
  2. centos误删除文件如何恢复
  3. Windows Mobile使用Shared Memory(共享内存)进行IPC(进程间通信)的开发
  4. C++语言之继承中的特点
  5. UPS不间断电源常见故障及如何排除故障
  6. 全球与中国血管重建装置市场投资现状及发展规划建议报告2022-2028年
  7. 1.7 编程基础之字符串 27 单词翻转 4分 python
  8. 2012 php mysql_Apache+Mysql+PHP(win sercer2012)
  9. [转]bookmark整理之.NET编程相关
  10. java 获取本机的IP和hostname
  11. COdeSmith的教程 CHM格式
  12. 8.21. Pseudo-Types
  13. 计算机应用oas,基于XML的OAS生成平台的研究与实现-计算机应用技术专业论文.docx...
  14. 就业前景php,php的就业前景如何
  15. 一个简单的俄罗斯方块实现
  16. 使用ONVIF Device Test Tool获取网络摄像头的音/视频
  17. Android的ADB
  18. 区块链零知识证明:STARKs, Part II
  19. Vue3 的生命周期函数
  20. 如何将影像变换为北京54坐标系

热门文章

  1. .NET界面控件DevExpress发布v18.2.4|附下载
  2. 【转】Java 专业词汇
  3. ElasticSearch工作原理解读及一些思考
  4. 场景法(流程图法)、错误推测法
  5. 卡牌NFT游戏的角逐:Shiryo能否脱颖而出?
  6. fog(雾)和haze(霾)区别
  7. div css 下划线text-decoration
  8. docker-comose安装失败解决
  9. TEC-2机微程序设计实验
  10. JavaScript:Ajax