C++ 之 线性插值 贝塞尔曲线 非线性动画

news2024/11/24 6:29:47

        非线性动画在程序,游戏和动画中运用非常广泛,那么我们应该如何实现?

非线性动画上的点在s-t图像上非线性,即不为一次函数,实则为处处连续的曲线

        对于此曲线可模拟,这里我们用贝塞尔曲线

一,基本介绍

        在某一时刻t s时,AE/AB=BF/BC=EG/EF

        想象在平面内有点A,B,C,线段AB,CB上分别有动点E,F,且E,F与其起始点(A,B)距离在一定时间内占所在线段的比例相同,在线段EF上有点G,其机制和E,F相同,则可想像到G点运动轨迹成曲线

这就是二次贝塞尔曲线

二,线性插值

        好,你已经基本了解我们所做的,即模拟G点轨迹完成曲线模拟

        想要完成这项任务就必须求得G点轨迹,我们需要一个描述单片运动的函数:

lerp函数

        在平面直角坐标系yOx内有两定点AB,E点为在线段AB上运动的动点

若使w=AE/AB,w∈[0, 1.0]
易得向量OE=OA+AE
∵AE=wAB
∴OE=OA+wAB
即对于结构体Point E=A+w(B-A)=A-wA+wB=(1-w)A+wB
有函数f(A, B, w)=(1-w)A+wB
此函数描述了在1s(w为时间,w∈[0, 1.0])内动点E在线段AB上的运动

这个函数就叫线性插值,记作lerp(A, B, t)

三,求G点轨迹

        我们基本上完成了对一个线性插值点运动状态描述的普遍函数,现在我们利用它来完成G点运动轨迹

E=lerp(A, B, t) , F=lerp(B ,C, t)

        t是描述运动的时间,在0-1s间,同时也可视作对于每个线性插值点中的w(weight权重,即为AE/AB=BF/BC=EG/EF),这样我们保障了对于每个线段插入点的运动相等性----在t=0时同时运动,t=1时同时停止运动

同样的,G=lerp(E, F, t)

        所以G点的轨迹也就呼之欲出了:

E=lerp(A, B, t)
F=lerp(B ,C, t)
G=lerp(E, F, t)
G=lerp(lerp(A, B, t) , lerp(B ,C, t), t)
=>  G=lerp((1-t)A+tB, (1-t)B+tC, t)
=(1-t)[(1-t)A+tB]+t[(1-t)B+tC]
=(1-t)^2 A+2t(1-t)B+t^2 C

        这就是二次贝塞尔曲线方程,三次同理

我们来用C++模拟一下:

代码如下:

        G点轨迹在21行,IDE是小熊猫C++,环境Win11,绘图库为EGE

效果:

        嗯,总的来说效果还行

        接下来,有了曲线方程,我们可以开始做一下非线性

四,非线性动画

这里以二次贝塞尔曲线为例

        想要达到非线性效果,就得让角色运动速度是非线性的(废话)

        即使物体运动速度会随时间发生变化(加速度改变):v/t=a≠C

        将贝塞尔曲线放在以A为原点的v-t坐标系上,令A.y=C.y,显然这就是一个非线性的运动图

        红线为所得G点轨迹

        将红线标为函数g(t)

        则由简单的微分知识可以知道

角色运动加速度a=v/t=lim(Δt→0) g(t+Δt)/Δt

        由于步长有限,而且动画不需要太过精确,所以这里我们取Δt=step(步长,程序中我取在0.001)

那么加速度a=(G.y-G'y)/(G.x-G'.x)

        这里的G‘是指上一步(上一个单位时常step中)G的位置

        这样我们便通过二次贝塞尔曲线完成了加速度的变化

        这意味着我们可以以此更改物体移动的瞬时速率(加速度),从而使物体在运动时速度随着时间连续变化

        这样我们只需要将物体运动速度在每次刷新加上加速度,就能实现非线性了:

        效果就不展示了

代码如下:

自己复制试一下:

#include<bits/stdc++.h>
#include<ege.h>

#define get_key(k) (GetAsyncKeyState(k)&0x8000)
using namespace std;
using namespace ege;

float t = 0, step = 0.01;
ege_point A, B, C;
ege_point G = {0.0, 0.0}, nG = {100000, 1};
float v = 0.0, x = 1280, y = 240, r = 10;
float wt = 1, wv = 0.1; //wt偏移调整加速度和曲线相关性 wv速度缩放值

int main() {
    A = {0, 480}, B = {240, 0}, C = {480, 480};
    initgraph(2560, 480);
    getch();
    setcolor(YELLOW);
    while (t < 1) {        
        G = {(1 - t)*(1 - t)*A.x + 2 * t*(1 - t)*B.x + t*t * C.x, (1 - t)*(1 - t)*A.y + 2 * t*(1 - t)*B.y + t*t * C.y};
        float delta = (G.y - nG.y) / (G.x - nG.x);
        nG = G;
        t += step;
        Sleep(0);
        cleardevice();
        circle(x, y, r);
        v += (wt * delta);
        x += (v * wv);
        cout << "delta_v " << v << endl;
    }
    system("pause");
    return 0;
}

五,结语

        本期教程我们经历了从发现问题→抽象问题→建立模型→解决问题→实际应用的过程,这是我们共同的进步

        在处理问题我们也运用了加速度,函数,导数,方程等等知识,这是我们综合应用和解决问题的能力的重要飞跃!

        数学是强有力的工具,这个世界上的任何问题都能转化为数学问题愿你我共同思考,共同进步!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/871292.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Azure DevOps基于 Net6.0 的 WPF 程序如何进行持续集成、持续编译

正文 1&#xff0c; Azure DevOps 创建项目 Project name&#xff1a;”NetCore_WPF_Sample“ Visibility&#xff1a;”Private“&#xff08;根据实际项目需求&#xff09; Version control&#xff1a;”Git“ Work item process&#xff1a;”Agile“ 点击 ”Create“…

【linux】2 软件管理器yum和编辑器vim

目录 1. linux软件包管理器yum 1.1 什么是软件包 1.2 关于rzsz 1.3 注意事项 1.4 查看软件包 1.5 如何安装、卸载软件 1.6 centos 7设置成国内yum源 2. linux开发工具-Linux编辑器-vim使用 2.1 vim的基本概念 2.2 vim的基本操作 2.3 vim正常模式命令集 2.4 vim末行…

【设计模式】MVC 模式

MVC 模式代表 Model-View-Controller&#xff08;模型-视图-控制器&#xff09; 模式。这种模式用于应用程序的分层开发。 Model&#xff08;模型&#xff09; - 模型代表一个存取数据的对象或 JAVA POJO。它也可以带有逻辑&#xff0c;在数据变化时更新控制器。View&#xff…

【爬虫】爬取旅行评论和评分

以马蜂窝“普达措国家公园”为例&#xff0c;其评论高达3000多条&#xff0c;但这3000多条并非是完全向用户展示的&#xff0c;向用户展示的只有5页&#xff0c;数了一下每页15条评论&#xff0c;也就是75条评论&#xff0c;有点太少了吧&#xff01; 因此想了个办法尽可能多爬…

Linux 终端命令之文件浏览(2) more

Linux 文件浏览命令 cat, more, less, head, tail&#xff0c;此五个文件浏览类的命令皆为外部命令。 hannHannYang:~$ which cat /usr/bin/cat hannHannYang:~$ which more /usr/bin/more hannHannYang:~$ which less /usr/bin/less hannHannYang:~$ which head /usr/bin/he…

最新智能AI系统+ChatGPT源码搭建部署详细教程+知识库+附程序源码

近期有网友问宝塔如何搭建部署AI创作ChatGPT&#xff0c;小编这里写一个详细图文教程吧。 使用Nestjs和Vue3框架技术&#xff0c;持续集成AI能力到AIGC系统&#xff01; 增加手机端签到功能、优化后台总计绘画数量逻辑&#xff01;新增 MJ 官方图片重新生成指令功能同步官方 …

nginx负载均衡配置过程

一、环境说明 主机名IPnginx服务器nginx-server192.168.198.141web页面1web1192.168.198.100web页面2web2192.168.198.200 关闭所有主机的防火墙和Selinux服务 二、配置过程 自定义页面 自定义web1和web2的页面 主配置文件 查看nginx的主配置文件 vim /usr/local/nginx/c…

全球八分之一的河流受到缺氧影响

一项全球研究发现&#xff0c;世界各地河流中的溶解氧含量低得危险。缺氧的真实发生率可能更高。 小型、低梯度的城市河流&#xff0c;例如图中北卡罗来纳州的那条河流&#xff0c;是最容易缺氧的河流之一。图片来源&#xff1a;乔安娜布拉扎克 2023 年 3 月&#xff0c;《卫报…

LeetCode--HOT100题(29)

目录 题目描述&#xff1a;19. 删除链表的倒数第 N 个结点&#xff08;中等&#xff09;题目接口解题思路代码 PS: 题目描述&#xff1a;19. 删除链表的倒数第 N 个结点&#xff08;中等&#xff09; 给你一个链表&#xff0c;删除链表的倒数第 n 个结点&#xff0c;并且返回链…

Microsoft365家庭版1年订阅新功能及版本对比

Microsoft 365可帮助您工作、学习、组织、连接和创&#xff0c;只需一项方便的订阅&#xff0c;即可尽享具有 Microsft 365 的6款精品应用、可同时登录5 台设备&#xff08;包括 Windows、macOS、iOS 和 Android 设备&#xff09;、高级安全性等&#xff0c;并且可以自由管理授…

升级STM32电机PID速度闭环编程:从F1到F4的移植技巧与实例解析

引言&#xff1a; 在嵌入式系统开发中&#xff0c;STM32系列微控制器广泛应用于各种应用领域。而对于直流有刷电机的控制&#xff0c;PID速度闭环是一种常用的控制方式。本文将以此为例&#xff0c;探讨如何从STM32F1系列移植到STM32F4系列&#xff0c;并详细介绍HAL库在不同型…

渗透测试验证码爆破实操

一、准备工具 captcha-killer-modified 下载路径 https://github.com/f0ng/captcha-killer-modified https://github.com/f0ng/captcha-killer-modified/releases/download/0.21-beta/captcha-killer-modified-0.21-beta-jdk11.jar 二、安装工具 burp安装captcha-killer-modif…

登录验证码实现

Hutool代码改造 Hutool 有参考文档&#xff1b;很多工具类&#xff1b;把一些功能都封装好&#xff1b;都不用你自己去写&#xff1b;直接调用它的工具类 它这里会详细告诉你引入方式Hutool <dependency><groupId>cn.hutool</groupId><artifactId>hu…

【第二阶段】kotlin语言的内联-inline关键字

1.函数如果没有使用lambda作为参数&#xff0c;就不需要声明成内联 2.函数如果使用lambda作为参数&#xff0c;就需要声明成内联&#xff0c;如果不使用内联&#xff0c;在调用端会生成多个对象来完成lambda的调用&#xff0c;会造成性能的损耗 3.函数如果使用lambda作为参数&a…

模板Plus【完整版】

文章目录 1.非类型模板参数的引入2.标准库和普通数组3.模板的特化3.1介绍3.2代码讲解3.3画图讲解 4.类、函数模板特化初识5.全特化与偏特化6.模板不能分离编译1.typename的使用2.预处理相关知识3.为什么不能分离编译&#xff1f;4.怎么解决&#xff1f;5.代码详解1.vector.h2.v…

实战篇之基于二进制思想的用户标签系统(Mysql+SpringBoot)

一&#xff1a; 计算机中的二进制 计算机以二进制表示数据&#xff0c;以表示电路中的正反。在二进制下&#xff0c;一个位只有 0 和 1 。逢二进一 位。类似十进制下&#xff0c;一个位只有 0~9 。逢十进一位。 二&#xff1a; 进制常用运算 &#xff08;位运算&#xff09;…

QT之时钟

QT之时钟 会用到一个时间类:qtime 定时类:qtimer #------------------------------------------------- # # Project created by QtCreator 2023-08-13T10:49:31 # #-------------------------------------------------QT += core guigreaterThan(QT_MAJOR_VERSION,…

基于Yolov8与LabelImg训练自己数据的完整流程

基于Yolov8与LabelImg训练自己数据的完整流程 1. 创建虚拟环境2. 通过git 安装 ultralytics3. 安装完成之后&#xff0c;通过以下代码测试下环境配置是否正确4. 安装labelImg标注软件5. 使用labelImg进行标注&#xff0c;图片使用上面的coco1285.1 点击“打开目录”选择存储图像…

如何看待40岁还在做程序员?

1&#xff0c;40岁还在做程序员是好还是坏&#xff1f; 2&#xff0c;40岁从零开始学习软件开发&#xff0c;四年后我成了首席研发 40岁了还在做程序员&#xff0c;是一个好还是坏的选择&#xff0c;这是一个很复杂的问题&#xff0c;因为每个人的情况都是不同的。在这里提供一…