C++模拟牛顿力学(2D)

news2024/11/24 6:23:25

简介

如何用计算机来模拟真实世界呢?计算机最大的功能是计算,而物理学的种种公式就把现实世界中的物理规律以数学的语言描绘了出来,从而使我们可以通过计算大致模拟现实世界的物体运动。因此不难想到把物理学定律(这里用的是牛顿力学)用计算机语言描述出来,模拟现实世界。这个项目就用C++实现了此功能,为了方便,目前实现的是二维宇宙。
项目完成后,只要输入各项参数,我们就可以用它模拟现实中的运动了。下面是用该项目模拟某飞船围绕某恒星运动的过程(注意,运动轨迹并不是预设的动画,而是通过计算得出的)。

代码

完整代码如下:

namespace NewtonianPhysics
{
	using Scalar = long double;//标量
	const Scalar G = 6.67259e-11l;//万有引力常数
	namespace _2D
	{
		class Vector//矢量
		{
		public:
			Scalar x;
			Scalar y;
			Vector() :x(0.l), y(0.l) {}
			Vector(Scalar inX, Scalar inY) :x(inX), y(inY) {}
			friend Vector operator+(const Vector& a, const Vector& b)
			{
				return Vector(a.x + b.x, a.y + b.y);
			}
			friend Vector operator-(const Vector& a, const Vector& b)
			{
				return Vector(a.x - b.x, a.y - b.y);
			}
			friend Vector operator*(const Vector& vec, Scalar n)
			{
				return Vector(vec.x * n, vec.y * n);
			}
			friend Vector operator*(Scalar n, const Vector& vec)
			{
				return Vector(vec.x * n, vec.y * n);
			}
			Vector& operator*=(Scalar n)
			{
				x *= n;
				y *= n;
				return *this;
			}
			Vector& operator+=(const Vector& right)
			{
				x += right.x;
				y += right.y;
				return *this;
			}
			Vector& operator-=(const Vector& right)
			{
				x -= right.x;
				y -= right.y;
				return *this;
			}
			Scalar LengthSq() const
			{
				return (x * x + y * y);
			}
			Scalar Length() const
			{
				return (std::sqrt(LengthSq()));
			}
			void Normalize()
			{
				float length = Length();
				x /= length;
				y /= length;
			}
			static Vector Normalize(const Vector& vec)
			{
				Vector temp = vec;
				temp.Normalize();
				return temp;
			}
		};
		class MassPoint
		{
		public:
			Scalar m;//质量/kg
			Vector location;//当前位置
			Vector v;//速度/(m/s)
			Vector f;//受到的合力/(N)
			MassPoint(Scalar mass, Vector _location = { 0,0 }, Vector velocity = { 0,0 })
				:m(mass), location(_location), v(velocity) {}
			void Update(Scalar deltaTime)
			{
				//由F=ma得出加速度并更新速度
				v += f * (1 / m) * deltaTime;
				//由速度得出位移并更新坐标
				location += v * deltaTime;
			}
		};
	}
}

标量和矢量

首先,我们定义了标量和矢量的类型。标量就是只有大小的量,如时间、质量等,而矢量是既有大小又有方向的量,如速度、加速度。标量用内置的long double类型即可。
矢量就是数学中的向量,在这里我们用Vector类来表示。根据数学定理,任何一个矢量都可以用平面直角坐标系中的一个坐标来表示。在Vector类里面,我们用两个标量来表示横坐标和纵坐标,并且定义了矢量的加法、减法、与实数的乘法。Length函数的作用是求矢量的长度,而LengthSq则是求矢量长度的平方。因为Length函数需要开方,速度比较慢,所以能用LengthSq就尽量用LengthSq。而Normalize函数的作用则是将矢量变成方向相同、长度为1的单位矢量。

增量时间

根据主流物理学理论,时间是连续的,然而,通过计算机模拟现实世界时,我们只能“一帧一帧”地计算。例如,如果我们每一帧代表0.1s,当前物体速度为10m/s,我们只能默认在这0.1s内物体的速度保持10m/s不变,尽管实际上速度可能变化了。这有点类似于微分,然而微分可以引入无穷小量,而计算机计算每一帧的时间不可能是无穷小,所以计算出来和实际结果一定有误差。并且,每帧代表的时间越短,误差越小。
在上面的例子中,0.1s就叫做增量时间( Δ t ) \Delta t) Δt)

质点

牛顿力学的核心就是将物体抽象成质点(有质量无大小的点)进行研究。这里的MassPoint类就表示质点。在MassPoint类的成员变量中,m表示质量,v表示当前的速度,f表示受到的合力,location是当前的坐标。
Update函数根据物理定律对质点的状态进行更新,它的参数就是增量时间。在这个函数中,我们先通过牛顿第二定律求出加速度,然后乘以增量时间得出速度,再乘以时间便得出了位移。

这样,我们便实现了牛顿力学的基本功能。

实例

下面是简介中飞船围绕恒星运动的代码示例(绘图用了easyx):

using namespace NewtonianPhysics;
void Print(const _2D::MassPoint& p)
{
	setfillcolor(YELLOW);
	setlinecolor(RED);
	setlinestyle(PS_SOLID, 1);
	auto x = (p.location.x + 2e7) * 800 / 4e7, y = (2e7 - p.location.y) * 800 / 4e7;
	fillcircle(x, y, 5);
}
int main()
{
	initgraph(800, 800); 
	_2D::MassPoint a(5e30l, { 0,0 }), b(1e4, { 1e7,0 }, { 0,5e6 });
	while (1)
	{
		cleardevice();
		Print(a);
		Print(b);
		Sleep(100);
		//F=GMm/r²
		b.f = _2D::Vector::Normalize(a.location - b.location) * (G * a.m * b.m / (a.location - b.location).LengthSq());		a.Update(0.05);
		b.Update(0.1);
	}
	closegraph();
	return 0;
}

该代码中,恒星的质量为 5 × 1 0 30 k g 5\times10^{30}kg 5×1030kg,且位于 ( 0 , 0 ) (0,0) (0,0)静止不动;飞船的质量为 1 × 1 0 4 k g 1\times10^4kg 1×104kg,初始位于 ( 1 × 1 0 7 , 0 ) (1\times10^7,0) (1×107,0),并且具有向上 5 × 1 0 6 m / s 5\times10^6m/s 5×106m/s的初速度。通过万有引力公式实时计算出恒星对飞船的引力,并调用Update函数进行更新。这样便实现了模拟运动。当然,大家也可以调节这些数据,或者加入更多的元素,实现更加复杂的运动过程(例如三体运动)。
这一期就先讲到这里,如果喜欢别忘了点个赞!

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

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

相关文章

SAP-MM-维护物料主数据的类(Class)和特性(Characteristic)

一.说明 物料主数据有千个左右条目,但仍不能满足各类物料自有特性的描述,为此SAP启用了类(Class)和特性(Characteristic),并在物料主数据的分类视图(Characteristic&…

推荐一款免费开源的代码质量分析工具

文章目录 一、简介二、环境安装三、使用说明四、其他报错UnicodeDecodeError: ‘ascii’ codec can’t decode byte 0xe6 in position 29: ordinal not in range(128)**linux:****windos:** 五、安全编程规范 一、简介 Flawfinder是一款开源的关于C/C静态扫描分析工具&#xf…

C++入门——关键字|命名空间|输入输出

前言: 今天我们又开启了一个崭新的大门——C面向对象编程语言,C是怎么来的呢?答案是:因为C语言的有很多不足,我们的祖师爷用着不爽,就不断更改,就改出来了一门新的语言,C。C语言兼容…

黑客常用的十大工具(附工具安装包),你知道几款?

注:本文总结白帽黑客常用的十大工具。文档仅供参考,不得用于非法用途,否则后果自负。 1 Nmap nmap是一个网络连接端扫描软件,用来扫描网上电脑开放的网络连接端。确定哪些服务运行在哪些连接端,并且推断计算机运行哪个…

谈谈开源的利弊和国内的开源 ——《新程序员005:开源深度指南 新金融背后的科技力量》书评

感谢CSDN的送测 《新程序员005:开源深度指南 & 新金融背后的科技力量》 是一本以计算机编程和金融科技为主题的杂志书,由中国最大的开源社区之一的开源社主办,内容丰富多样,包括了众多知名开源项目和工具的介绍,同…

第 3 章:使用 Vue 脚手架

目录 具体步骤 模板项目的结构(脚手架文件结构) Vue脚手架报错 修改方案: 关于不同版本的Vue vue.config.js配置文件 ref属性 props配置项 mixin(混入) 插件 小结: scoped样式 小结: Todo-list 案例 小结…

kafka重点问题解答-----kafka 的设计架构

1. kafka 都有哪些特点? 高吞吐量,低延迟 可以热扩展 并发度高 具有容错性(挂的只剩1台也能正常跑) 可靠性高 2. 请简述你在哪些场景下会选择 kafka? kafka的一些应用 日志收集:一个公司可以用kafka可以收集各种服务的log&…

自学黑客(网络安全/web渗透),一般人我还是劝你算了吧

由于我之前写了不少网络安全技术相关的文章,不少读者朋友知道我是从事网络安全相关的工作,于是经常有人私信问我: 我刚入门网络安全,该怎么学? 要学哪些东西? 有哪些方向? 怎么选&a…

chatgpt赋能python:Python分解三位数:打造高效的数学学习工具

Python分解三位数:打造高效的数学学习工具 介绍 Python是一种动态、解释型、高级编程语言,广泛应用于数据分析、人工智能、机器学习等领域。在数学教育中,Python也是一个非常好的工具,可以帮助学生更好地理解数学知识和提高解题…

Linux内核模块开发 第 6 章

The Linux Kernel Module Programming Guide Peter Jay Salzman, Michael Burian, Ori Pomerantz, Bob Mottram, Jim Huang译 断水客(WaterCutter) 6 字符设备驱动 include/linux/fs.h 中定义了结构体 file_operations ,这个结构体包含指…

深度学习论文分享(三)Look More but Care Less in Video Recognition(NIPS2022)

深度学习论文分享(三)Look More but Care Less in Video Recognition(NIPS2022) 前言Abstract1. Introduction2 Related Work2.1 Video Recognition2.2 Redundancy in Data(数据冗余) 3 Methodology3.1 Arc…

Apache 虚拟主机企业应用

企业真实环境中, 一台服务器发布单个网站非常浪费资源,所以一台 web 服务器上会发布多个网站少则2~3个多则 30多个网站 在一台服务器上发布多网站,也称之为部署多个虚拟主机, Web 虚拟主机配置方法有以下 种: 1、基于单…

基于机器学习的内容推荐算法及其心理学、社会学影响闲谈

基于机器学习的内容推荐算法目前在各类内容类APP中使用的非常普遍。在购物、时尚、新闻咨询、学习等领域,根据用户的喜好,进行较为精准的用户画像与内容推荐。此类算法不但可以较为准确的分析用户的特征,如年龄、性别等,还能通过长…

QT项目实战(视频播放器)

文章目录 前言一、QMediaPlayer二、QVideoWidget三、QAudioOutput四、播放器代码实现五、最终效果总结 前言 本篇文章将使用QT6.4来实现一个简单视频播放器,在QT中使用一个视频播放器还是非常简单的。那么下面就让我们一起来实现这个视频播放器吧。 一、QMediaPla…

深度学习应用篇-计算机视觉-图像增广[1]:数据增广、图像混叠、图像剪裁类变化类等详解

【深度学习入门到进阶】必看系列,含激活函数、优化策略、损失函数、模型调优、归一化算法、卷积模型、序列模型、预训练模型、对抗神经网络等 专栏详细介绍:【深度学习入门到进阶】必看系列,含激活函数、优化策略、损失函数、模型调优、归一化…

基于VGG16实现宝石图像分类任务(acc 84%)--paddle paddle

作业:补充网络定义部分,使用卷积神经网络实现宝石分类 要求:1.补充完成CNN的网络结构定义方法实现宝石识别 2.可尝试不同网络结构、参数等力求达到更好的效果 卷积神经网络 卷积神经网络是提取图像特征的经典网络,其结构一般包…

【hello C++】类和对象(下)

目录 1. 再谈构造函数 1.1 构造函数体赋值 1.2 初始化列表 1.3 explicit关键字 2. static成员 2.1 概念 2.2 特性 3. 友元 3.1 友元函数 3.2 友元类 4. 内部类 5.匿名对象 6.拷贝对象时的一些编译器优化 7. 再次理解类和对象 1. 再谈构造函数 1.1 构造函数体赋值 在创建对象…

Spring Boot项目使用 jasypt 加密组件进行加密(例如:数据库、服务的Key、等等进行加密)

🍓 简介:java系列技术分享(👉持续更新中…🔥) 🍓 初衷:一起学习、一起进步、坚持不懈 🍓 如果文章内容有误与您的想法不一致,欢迎大家在评论区指正🙏 🍓 希望这篇文章对你有所帮助,欢…

【018】C++的指针数组和数组指针

C 指针数组和数组指针 引言一、指针数组1.1、数值的指针数组1.2、字符的指针数组1.3、二维字符数组 二、指针的指针三、数组指针3.1、数组首元素地址和数组首地址3.2、数组指针的使用示例3.3、二维数组和数组指针的关系 四、多维数组的物理存储总结 引言 💡 作者简介…

从0实现基于Alpha zero的中国象棋AI(会分为多个博客,此处讲解蒙特卡洛树搜索)

从0实现基于Alpha zero的中国象棋AI 0.0、前言 ​ 题主对于阿尔法狗的实现原理好奇,加上毕业在即,因此选择中国象棋版的阿尔法zero,阿尔法zero是阿尔法狗的升级版。在完成代码编写的历程中,深刻感受到深度学习环境的恶劣&#x…