用manim实现内燃机引擎的活塞,连杆和曲柄的模拟运动【上】

news2024/10/16 12:49:24

一,介绍

内燃机引擎是现代机械设备中一种非常重要的动力装置,其核心部件包括活塞、连杆和曲柄。活塞在气缸内做往复运动,通过连杆与曲柄相连,将往复运动转化为旋转运动,驱动机械设备正常工作。

活塞是内燃机引擎的关键部件之一,它在气缸内作往复运动。当活塞向上运动时,气缸内形成真空,进气门打开,混合气体进入气缸内;当活塞向下运动时,气缸内形成压缩,进气门关闭,同时点火系统点燃混合气体,产生爆炸力推动活塞向上运动。这一过程不断重复,驱动曲柄旋转,输出动力。

连杆是活塞与曲柄间的连接部件,将活塞的往复运动转化为连续旋转运动。连杆一端连接活塞,另一端连接曲柄,当活塞运动时,连杆带动曲柄旋转,实现活塞能量的转换和传递。

曲柄是内燃机引擎中的重要传动部件,其主要作用是将连杆的往复运动转化为旋转运动,输出动力。曲柄由曲轴和连杆轴组成,当连杆带动曲柄旋转时,曲轴转动,驱动机械设备正常运转。

总的来说,活塞、连杆和曲柄之间的协同作用实现了内燃机引擎的正常运转,是内燃机引擎的核心动力传动装置,是现代机械工业发展的重要基础。

二,用manim实现简易动画

首先找到每个运动单元之间的关系。然后进一步进行动画

第一步:找到相关的点

from manim import *  # 从manim库导入所有必需的类和函数  

class MechanismEngine03(Scene):  # 创建一个名为MechanismEngine03的类,继承自Scene类  
    def construct(self):  # 定义构建场景的方法  
        # 创建固定点A,设置其位置和颜色  
        point_A = Dot(point=np.array([0, -2, 0]), color=RED)  # 在 (0, -2, 0) 处创建一个红色点A  
        self.add(point_A)  # 将点A添加到场景中  

        # 创建一个圆,圆心在A,半径为1  
        radius = 1  # 定义圆的半径  
        circle = Circle(radius=radius, color=BLACK)  # 创建一个半径为1,颜色为黑色的圆  
        circle.move_to(point_A.get_center())  # 将圆心移动到点A的位置  
        self.add(circle)  # 将圆添加到场景中  

        # 创建点B,初始位置在圆的右侧  
        point_B = Dot(point=circle.point_at_angle(0), color=BLUE)  # 在圆的右侧 (1, 0, 0) 处创建一个蓝色点B  
        self.add(point_B)  # 将点B添加到场景中  

        # 创建点C,初始位置为 (0, 2, 0)  
        point_C = Dot(point=np.array([0, 2, 0]), color=GREEN)  # 创建一个绿色点C,其初始位置为 (0, 2, 0)  
        self.add(point_C)  # 将点C添加到场景中  

        # 动画设置  
        run_time = 8  # 定义整个动画持续的时间为8秒  
        total_frames = 100  # 定义总帧数为100帧  
        angle_step = 2 * PI / total_frames  # 每帧的角度增量,整个圆周是 2π,除以帧数得到每帧的角度变化  

        # 旋转点B沿着圆周移动  
        for frame in range(total_frames):  # 遍历每一帧,执行总帧数的动画  
            angle_B = frame * angle_step  # 计算当前帧对应的角度  
            point_B.move_to(circle.point_at_angle(angle_B))  # 更新点B的位置,沿着圆周的当前角度进行移动  

            # 根据点B的位置更新点C的位置  
            point_C.move_to(np.array([0, point_B.get_center()[1] + 2, 0]))  # 使点C的位置更新为相对于点B的y坐标加2  

            # 更新动画  
            self.play(  # 播放动画  
                point_B.animate.move_to(circle.point_at_angle(angle_B)),  # 使点B移动到圆周上的新位置  
                point_C.animate.move_to(np.array([0, point_B.get_center()[1] + 2, 0])),  # 使点C移动到更新后的位置  
                run_time=run_time / total_frames,  # 每帧的动画持续时间为总时间除以帧数  
                rate_func=linear  # 使用线性插值函数  
            )  

        self.wait(2)  # 动画结束后等待2秒

 

代码解释

该代码使用Manim库创建一个动画场景,其中有以下几个关键部分:

  1. 创建点和圆

    • 点A:固定点,作为圆心。
    • :以点A为圆心,半径为1。
    • 点B:初始位置在圆的右侧(与圆心正对)。
    • 点C:初始位置在y=2的位置。
  2. 动画设置

    • 动画总时间为8秒,总共100帧。
    • 根据总帧数计算每帧对应的角度变化。
  3. 动画循环

    • 每一帧中,计算点B的新位置,并根据点B的位置相对更新点C的位置。
    • 使用self.play方法来更新点B和点C的位置,并播放动画。
  4. 动画结束的等待

    • 动画结束时,场景会保持2秒,便于观察最终结果。

这种方式展现了一个简单的机械运动,适合展示线性和周期性运动。

第二部,加连杆结构 

该代码使用Manim库创建一个动画,展示一个点B沿着固定圆周旋转,同时更新与之相连的点C和线段AB、BC的运动。

from manim import *  # 从manim库导入所有必需的类和函数  

class MechanismEngine04(Scene):  # 创建一个名为MechanismEngine04的类,继承自Scene类  
    def construct(self):  # 定义构建场景的方法  
        # 创建固定点A,作为圆心  
        point_A = Dot(point=np.array([0, -2, 0]), color=RED)  # 在 (0, -2, 0) 处创建一个红色点A  
        self.add(point_A)  # 将点A添加到场景中  

        # 创建一个圆,圆心在A,半径为1  
        radius = 1  # 定义圆的半径  
        circle = Circle(radius=radius, color=BLACK)  # 创建一个半径为1,颜色为黑色的圆  
        circle.move_to(point_A.get_center())  # 将圆心移动到点A的位置  
        self.add(circle)  # 将圆添加到场景中  

        # 创建点B,初始位置在圆的右侧  
        point_B = Dot(point=circle.point_at_angle(0), color=BLUE)  # 在圆的右侧 (1, 0, 0) 处创建一个蓝色点B  
        self.add(point_B)  # 将点B添加到场景中  

        # 创建点C,初始位置为 (0, 2, 0)  
        point_C = Dot(point=np.array([0, 2, 0]), color=GREEN)  # 创建一个绿色点C,其初始位置为 (0, 2, 0)  
        self.add(point_C)  # 将点C添加到场景中  

        # 创建线段AB和BC  
        line_AB = Line(start=point_A.get_center(), end=point_B.get_center(), color=YELLOW)  # 创建一条从点A到点B的黄色线段  
        line_BC = Line(start=point_B.get_center(), end=point_C.get_center(), color=PURPLE)  # 创建一条从点B到点C的紫色线段  
        self.add(line_AB, line_BC)  # 将线段AB和BC添加到场景中  

        # 动画设置  
        run_time = 8  # 定义整个动画持续的时间为8秒  
        total_frames = 100  # 定义总帧数为100帧  
        angle_step = 2 * PI / total_frames  # 每帧的角度增量,整个圆周是 2π,除以帧数得到每帧的角度变化  

        # 旋转点B沿着圆周移动  
        for frame in range(total_frames):  # 遍历每一帧,执行总帧数的动画  
            angle_B = frame * angle_step  # 计算当前帧对应的角度  
            point_B.move_to(circle.point_at_angle(angle_B))  # 更新点B的位置,沿着圆周的当前角度进行移动  

            # 根据点B的位置更新点C的位置  
            point_C.move_to(np.array([0, point_B.get_center()[1] + 2, 0]))  # 使点C的位置更新为相对于点B的y坐标加2  

            # 更新线段AB和BC  
            line_AB.put_start_and_end_on(point_A.get_center(), point_B.get_center())  # 更新线段AB的起点和终点  
            line_BC.put_start_and_end_on(point_B.get_center(), point_C.get_center())  # 更新线段BC的起点和终点  

            # 更新动画  
            self.play(  # 播放动画  
                point_B.animate.move_to(circle.point_at_angle(angle_B)),  # 使点B移动到圆周上的新位置  
                point_C.animate.move_to(np.array([0, point_B.get_center()[1] + 2, 0])),  # 使点C移动到更新后的位置  
                line_AB.animate.put_start_and_end_on(point_A.get_center(), point_B.get_center()),  # 更新线段AB的动画  
                line_BC.animate.put_start_and_end_on(point_B.get_center(), point_C.get_center()),  # 更新线段BC的动画  
                run_time=run_time / total_frames,  # 每帧的动画持续时间为总时间除以帧数  
                rate_func=linear  # 使用线性插值函数  
            )  

        self.wait(2)  # 动画结束后等待2秒,以便观察结果

代码解释

该代码使用Manim库创建了一个动态的机械运动场景,其中包含以下几个关键部分:

  1. 创建点和圆

    • 点A:作为圆心,固定在坐标(0, -2, 0)的位置。
    • :以点A为中心,半径为1,表示一个固定的圆周。
    • 点B:初始位置在圆的右侧(坐标(1, 0, 0)),表示沿圆周移动的点。
    • 点C:初始位置在(0, 2, 0),表示相对于点B的固定位置。
  2. 创建线段

    • 线段AB:连接点A和点B,颜色为黄色。
    • 线段BC:连接点B和点C,颜色为紫色。
  3. 动画设置

    • 动画总时间为8秒,分为100帧。
    • 计算每帧的角度增量,以便在动画中平滑地旋转点B。
  4. 动画循环

    • 在每一帧中,计算点B的新位置,并根据点B的位置更新点C的位置。
    • 更新线段AB和BC的起止点,以确保它们始终连接相应的点。
    • 使用self.play方法来更新点B、点C和线段AB、BC的位置,并播放动画。
  5. 动画结束的等待

    • 动画结束后,场景保持2秒,便于观察最终结果。

这个场景展示了一个简单的机械运动,点B沿着圆周旋转,点C根据点B的位置进行相对移动,同时线段AB和BC动态更新,形成了一个直观的运动演示。

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

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

相关文章

VSCode中的TypeScript教程

TypeScript 是JavaScript的类型化超集,可编译为纯JavaScript。它提供了类、模块和接口来帮助您构建健壮的组件。 安装 TypeScript 编译器 Visual Studio Code 包括 TypeScript 语言支持,但不包括 TypeScript 编译器tsc。您需要在全局或工作区中安装Typ…

【C语言】预编译+编译+汇编+链接

文章目录 翻译环境和运行环境翻译环境预处理(预编译)编译汇编链接 运行环境 接下来是预处理阶段的一系列知识,认真阅读哦预定义符号#define定义常量#define定义宏带有副作用的宏参数宏替换的规则宏函数的对比#和##命名约定#undef命令行定义条…

C++初阶(五)--类和对象(中)--默认成员函数

目录 一、默认成员函数(Default Member Functions) 二、构造函数( Constructor) 1.构造函数的基本概念 2.构造函数的特征 3.构造函数的使用 无参构造函数 和 带参构造函数 注意事项: 4.默认构造函数 隐式生成的…

恢复已删除文件的 10 种安卓数据恢复工具

由于我们现在在智能手机上存储了大量重要文件,因此了解数据恢复工具变得很重要。您永远不会知道什么时候需要使用 安卓 数据恢复工具。 由于不乏 Windows 数据恢复工具,因此从崩溃的计算机中恢复文件很容易。但是,当涉及到从 安卓恢复数据时…

大数据-171 Elasticsearch ES-Head 与 Kibana 配置 使用 测试

点一下关注吧!!!非常感谢!!持续更新!!! 目前已经更新到了: Hadoop(已更完)HDFS(已更完)MapReduce(已更完&am…

Go语言Gin框架的常规配置和查询数据返回json示例

文章目录 路由文件分组查询数据库并返回jsonservice层controller路由运行效果 启动多个服务 在 上一篇文章《使用Go语言的gorm框架查询数据库并分页导出到Excel实例》 中主要给大家分享了较多数据的时候如何使用go分页导出多个Excel文件并合并的实现方案,这一篇文章…

unity学习-全局光照(GI)

在全局光照(Lighting)界面有两个选项 Realtime Light(实时光照):在项目中会提前计算好光照以及阴影的程序,当你需要调用实时全局光照的时候会将程序调用出来使用 Mixed Light(烘焙光照&#x…

如何利用kafka实现高效数据同步?

在我们之前的文章有详细介绍过Kafka的结构、特点和处理方式。具备告诉处理能力的kafka被利用在数据同步和数据传输上,今天来说下kafka是怎么实现高效的数据同步和传输。 一、可靠的数据传输 1. 持久性保证:Kafka 将数据持久化到磁盘上,即使在…

汽车管理系统——主界面制作

目录 主界面需要有什么?然后要做什么?添加两个主菜单(声明)下一步应该干什么?能够跳转到文件有哪几个动作?动作如何声明?为什么用选择声明指针,不选择直接声明这个对象? …

算力基础篇:从零开始了解算力

什么是算力 算力即计算能力(Computing Power),狭义上指对数字问题的运算能力,而广义上指对输入信息处理后实现结果输出的一种能力。虽然处理的内容不同,但处理过程的能力都可抽象为算力。比如人类大脑、手机以及各类服…

git 与 github 同步

1.配置账户 git config --global user.name "你的用户名" git config --global user.email "你的邮箱" 2.输入命令创建ssh key $ ssh-keygen -t rsa -C "邮箱" //你自己注册GitHub的邮箱 输入命令之后提示输入密码,回车直到出现…

C++类(3)

1.如果一个类什么成员都没有,简称空类 但是空类真的什么都没有吗? 并不是,任何类什么都不写,编译器会自动生成以下6个默认成员函数 1.构造函数 class Date { public:void Init(int year, int month, int day){_year year;_mo…

kubernetes简介及安装部署

目录 一、kubernetes简介 1、k8s的概念 2、k8s各个组件及用途 3、k8s各组件之间的调用关系 4、k8s常用名词概念 5、k8s的分层架构 二、kubernetes安装部署 1、k8s集群环境搭建 2、本地解析、swap禁用 3、安装docker 4、复制harbor仓库中的证书并启动docker 5、设定d…

基于Cesium.js的可视化大屏,效果绝对的震撼!

基于 Cesium.js 的可视化大屏确实能带来震撼的效果。Cesium.js 强大的三维渲染能力,能够逼真地呈现地理信息和各种数据模型。 在大屏上,广袤的地形地貌、精细的建筑模型以及动态的数据展示,仿佛将观众带入一个全新的虚拟世界。无论是用于地理…

网络分析仪——提升网络性能的关键工具

目录 什么是网络分析仪? 1. 实时流量监控 2. 历史数据回溯分析 3. 网络性能关键指标监测 4. 可视化界面与报告生成 总结 在当今的数字化世界,网络的稳定性和性能直接影响企业的运营效率。网络拥堵、延迟和丢包等问题会导致用户体验的下降&#xff…

“屏” 步青云:轻松开启录屏功能,Windows 实例教学

你知道 Windows 的录屏功能怎么打开吗?在当今数字化时代,录屏功能成为了许多人工作、学习和娱乐中的得力助手。无论是制作教学视频、记录游戏精彩瞬间,还是为线上会议留存资料,掌握录屏技能都至关重要。今天我们不仅会介绍 Window…

springboot智能网上问诊系统-计算机毕业设计源码99634

摘要 智能网上问诊系统作为医疗健康领域的重要应用之一,为患者提供了便捷的医疗服务途径。本研究旨在基于Springboot框架设计和实现一套智能网上问诊系统,结合医疗专业知识,实现患者与医生之间的在线咨询和诊疗服务。 通过对Springboot框架…

如何从模块内部运行 Pytest

在 Python 中,pytest 是一个强大的测试框架,用于编写和运行测试用例。通常我们会在命令行中运行 pytest,但是有时你可能希望从模块或脚本的内部运行 pytest,比如为了自动化测试或集成到某个工作流程中。 1、问题背景 当你从模块…

网络爬虫-数美滑块验证码

仅供研究学习使用。 今天带来的是数美滑块验证码的逆向 目标站 --> 传送门 解决此类验证码 首先要解决滑动距离的判定 无论是使用selenium还是使用协议的方式来破解 都绕不开滑动距离的识别 滑动距离可以参考以前我博客上的方式,或者找一找开源的一些算法&am…

秋招突击——8/6——万得数据面试总结

文章目录 引言正文面经整理一1、讲一下java的多态,重载,重写的概念,区别2、说一下Java的数组,链表的结构,优缺点3、创建java线程的方式有哪些,具体说说4、创建线程池呢、每个参数的意义5、通过那几种方式保…