当前位置:网站首页>数学——贝塞尔曲线
数学——贝塞尔曲线
2022-04-22 14:52:00 【_雪菜肉丝面_】
目标
实现图中的运动。
代码准备
一个画布
结构:
<div id="app">
<div id="rectangle"></div>
</div>
表现:
#app {
width: 600px;
height: 600px;
margin: 0 auto;
outline: solid pink 2px;
position: relative;
}
#rectangle {
position: absolute;
width: 100px;
height: 100px;
background-color: red;
}
效果:

一些JS
代表坐标的类:
function Point2D(x = 0, y = 0) {
this.x = x
this.y = y
}
动画的状态:
//目标元素
let element = document.getElementById('rectangle')
//状态
let index = 0
let totalTime = 3000
let direction = true
element:动画的目标元素。
index:当前动画的百分比,每次加减0.01。范围为零到一。
totalTime:动画的总毫秒数。
direction:当前的运动方向。
一阶贝塞尔
这个网站可以观察贝塞尔的运动:https://www.jasondavies.com/animated-bezier/
一阶是匀速运动,每帧的坐标:
起点坐标加上当前偏移。
function BezierOne(from, to, step) {
let x = from.x + (to.x - from.x) * step
let y = from.y + (to.y - from.y) * step
return new Point2D(x, y)
}
实现一阶的运动:
let fromP = new Point2D(0, 0)
let toP = new Point2D(250, 0)
setInterval(() => {
if (index > 1 || index < 0) {
direction = !direction
}
if (direction) {
index += 0.01
} else {
index -= 0.01
}
let point = BezierOne(fromP, toP, index)
element.style.left = point.x + "px"
element.style.top = point.y + "px"
}, 0.01 * totalTime)
先判断边界,更改运动方向。
由运动方向确定下一帧的index。
计算贝塞尔坐标。赋值。
效果:

二阶贝塞尔
起点A,控制点B,终点C。
算出AB一阶,BC一阶。
再由这两个一阶计算一阶。(套娃)
function BezierTwo(from, to, control, step) {
let a = BezierOne(from, control, step)
let b = BezierOne(control, to, step)
return BezierOne(a, b, step)
}
多了一个点。
let fromP = new Point2D(0, 0)
let controlP = new Point2D(250, 0)
let toP = new Point2D(250, 500)
把调用改为二阶:
BezierTwo(fromP, toP, controlP, index)
效果:

三阶贝塞尔
起点A,控制点B,控制点C,终点D。
算出AB一阶,BC一阶,CD一阶。
再由这三个一阶计算二阶。(套娃)
function BezierThree(from, to, controlA, controlB, step) {
let a = BezierOne(from, controlA, step)
let b = BezierOne(controlA, controlB, step)
let c = BezierOne(controlB, to, step)
return BezierTwo(a, c, b, step)
}
又多了一个点:
let fromP = new Point2D(0, 0)
let controlA = new Point2D(250, 0)
let controlB = new Point2D(250, 500)
let toP = new Point2D(0, 0)
调用改为三阶:
BezierThree(fromP, toP, controlA, controlB, index)
效果:

四阶贝塞尔
起点A,控制点B,控制点C,控制点D,终点E。
算出AB一阶,BC一阶,CD一阶,DE一阶。
再由这四个一阶计算三阶。(套娃)
function BezierFour(from, to, controlA, controlB, controlC, step) {
let a = BezierOne(from, controlA, step)
let b = BezierOne(controlA, controlB, step)
let c = BezierOne(controlB, controlC, step)
let d = BezierOne(controlC, to, step)
return BezierThree(a, d, b, c, step)
}
又多了一个点:
let fromP = new Point2D(0, 0)
let controlA = new Point2D(250, 0)
let controlB = new Point2D(250, 500)
let controlC = new Point2D(0, 0)
let toP = new Point2D(0, 500)
调用改为四阶:
BezierFour(fromP, toP, controlA, controlB, controlC, index)
效果:

更多阶贝塞尔
不会真的有人用吧。
function BezierN(arr, step) {
if (arr.length === 2) {
return BezierOne(arr[0], arr[1], step)
} else {
let arr2 = []
for (let i = 0; i < arr.length - 1; i++) {
arr2.push(BezierOne(arr[i], arr[i + 1], step))
}
return BezierN(arr2, step)
}
}
看看四阶的,对不对。
let point = BezierN([fromP, controlA, controlB, controlC, toP], index)
效果:

全部代码
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style> #app {
width: 600px; height: 600px; margin: 0 auto; outline: solid pink 2px; position: relative; } #rectangle {
position: absolute; width: 100px; height: 100px; background-color: red; } </style>
</head>
<body>
<div id="app">
<div id="rectangle"></div>
</div>
<script> //目标元素 let element = document.getElementById('rectangle') //状态 let index = 0 let totalTime = 3000 let direction = true //起点,终点 let fromP = new Point2D(0, 0) let controlA = new Point2D(250, 0) let controlB = new Point2D(250, 500) let controlC = new Point2D(0, 0) let toP = new Point2D(0, 500) setInterval(() => {
if (index > 1 || index < 0) {
direction = !direction } if (direction) {
index += 0.01 } else {
index -= 0.01 } let point = BezierN([fromP, controlA, controlB, controlC, toP], index) element.style.left = point.x + "px" element.style.top = point.y + "px" }, 0.01 * totalTime) function Point2D(x = 0, y = 0) {
this.x = x this.y = y } function BezierOne(from, to, step) {
let x = from.x + (to.x - from.x) * step let y = from.y + (to.y - from.y) * step return new Point2D(x, y) } function BezierTwo(from, to, control, step) {
let a = BezierOne(from, control, step) let b = BezierOne(control, to, step) return BezierOne(a, b, step) } function BezierThree(from, to, controlA, controlB, step) {
let a = BezierOne(from, controlA, step) let b = BezierOne(controlA, controlB, step) let c = BezierOne(controlB, to, step) return BezierTwo(a, c, b, step) } function BezierFour(from, to, controlA, controlB, controlC, step) {
let a = BezierOne(from, controlA, step) let b = BezierOne(controlA, controlB, step) let c = BezierOne(controlB, controlC, step) let d = BezierOne(controlC, to, step) return BezierThree(a, d, b, c, step) } function BezierN(arr, step) {
if (arr.length === 2) {
return BezierOne(arr[0], arr[1], step) } else {
let arr2 = [] for (let i = 0; i < arr.length - 1; i++) {
arr2.push(BezierOne(arr[i], arr[i + 1], step)) } return BezierN(arr2, step) } } </script>
</body>
</html>
版权声明
本文为[_雪菜肉丝面_]所创,转载请带上原文链接,感谢
https://blog.csdn.net/qq_37284843/article/details/124343428
边栏推荐
- [ELT. Zip] openharmony paper Club - you shouldn't miss these small landscapes
- [elt.zip] openharmony's paper growth plan -- multidimensional exploration and universal lossless compression
- [C language] basic concepts of C language
- 【ORB_SLAM2源码解读】分析ORB_SLAM2 RGBD 第1帧是怎么计算位置姿态的
- Alibaba cloud IOT transfer to PostgreSQL database scheme
- [ELT. Zip] openharmony paper club -- turn over those immortal poems
- Kubecost | Kubernetes 开支监控和管理
- Awk command
- Which domestic foreign exchange platforms are safe and formal?
- net::ERR_INCOMPLETE_CHUNKED_ENCODING 200 EL表达式字符串拼接
猜你喜欢

【ELT.ZIP】OpenHarmony啃论文成长计划——多维探秘通用无损压缩

Static routing comprehensive experiment

web自动化测试框架通过js来实现对web元素的操作
![[elt.zip] openharmony's paper growth plan -- multidimensional exploration and universal lossless compression](/img/76/73c92acd32a51aa6e054da44205e23.png)
[elt.zip] openharmony's paper growth plan -- multidimensional exploration and universal lossless compression

redis优化系列(一)基于docker搭建Redis主从

【刷题日记】笔试经典编程题目(三)

VDO virtual data optimization

SQL Server 数据库之常量

干货!对有目标对抗图像迁移性的反思

Amazon Aurora 的读写能力扩展之 ShardingSphere-Proxy 篇
随机推荐
Share one (quick navigation)
[ELT. Zip] openharmony paper club -- turn over those immortal poems
People always simply think that the industrial Internet is a broader platform than the Internet
RIP简介
如何将来自 Chrome 网络选项卡的请求复制到 Postman?
memcpy( )函数复制二维数组 & memcmp( )函数比较二维数组
SMB+MSSQL
postMassage留个坑
一个青年的初识
Quickly understand what the dictionary in redis is
SQL Server 数据库之常量
In the second half of the smart watch, opportunities and challenges coexist
快捷键删除浏览器缓存,windows组合键,cmd快捷命令
C语言的基本练习(002-1)
flinkSQL 只有输入和输出的情况下,会合并成一个子任务,这种情况就无法显示出输入输出的数据量?
How to configure slo
[C language] basic concepts of C language
Mobile terminal adaptive and responsive layout
Rip introduction
Introduction notes to golang - redis