用Java模拟行星的运动

article/2025/1/15 18:23:16

        这段时间都在寝室里自学Java,就想自己写个小程序玩一玩。同时,我也是个三体迷,就想着能不能用学的Java来模拟一下三体运动。这个程序算是我正式写模拟三体运动前的一个尝试。

一、程序分析

         首先来百度一番查一下太阳、水星、金星和地球的各种参数(非精确):

         1.太阳:

                    质量:2.0\times 10^{30}kg

          2.水星:

                     质量:3.3\times 10^{23}kg

                     轨道半径:5.9\times10^{10}m

                     公转速度:4.8\times10^{4}m/s

           3.金星

                     质量:4.9\times10^{24}kg

                     轨道半径:1.1\times10^{11}m

                     公转速度:3.5\times10^{4}m/s

             4.地球

                     质量:6\times10^{24}kg

                     轨道半径:1.5\times10^{11}m

                     公转速度:3.0\times10^{4}m/s

      模拟的方式,我采用了万有引力公式和牛顿运动定律的微分形式来模拟。这种方法误差和计算量都比较大,但对这种粗略的模拟,还是可以的。首先用万有引力公式计算出各个行星受到的太阳引力(行星之间的引力就忽略不计了,没必要,当然加上也是可以的),进而计算出每个行星的加速度。用一个变量time来表示时间微元,用每个行星当前的速度vector乘以time就得到行星位移的微元,然后再将行星速度vector更新为vector+行星的加速度乘以时间,再将行星的位置画出来。将这些过程写在一个循环体里,就可宜不断更新行星的位置了。

       这里面用到的vector,加速度等都是向量,Java并没有处理向量运算的类,需要自己写一个自定义类Vector2D。每个行星也都定义为自定义类Actor类的子类。绘制行星等在Univers类中。程序入口为Main类。

        包结构

  1. main包:Main类
  2. vector2D包:Vector2D类
  3. actor包:Actor类       
  4. univers包:Univers类                                 

 二、代码编写

        1.Vector2D类

package Vector2D;
import java.awt.Point;public class Vector2D {public static Vector2D baseX = new Vector2D(1, 0);    //x方向的单位向量public static Vector2D baseY = new Vector2D(0, 1);    //y方向的单位向量private double x;			//向量的x坐标private double y;			//向量的y坐标private double model;		//向量的模private float theta;		//向量的辐角public Vector2D(double x,double y) {this.x = x;this.y = y;this.model = Math.sqrt(this.x*this.x+this.y*this.y);this.theta = (float) Math.atan(y/x);}public Vector2D(Point p1,Point p2) {x = p2.getX() - p1.getX();		y = p2.getY() - p1.getY();model = Math.sqrt(x*x+y*y);theta = (float) Math.atan(y/x);}public double getX() {return x;}public double getY() {return y;}public double getModel() {return model;}public double getTheta() {return theta;}//向量加法public Vector2D plus(Vector2D vector2D_2) {return new Vector2D(x+vector2D_2.getX(), y+vector2D_2.getY());}//向量减法public Vector2D sub(Vector2D vector2D_2) {return new Vector2D(x-vector2D_2.getX(),y-vector2D_2.getY());}//求相反向量public Vector2D inverse() {return new Vector2D(-x,-y);}//数乘public Vector2D multi(double r) {return new Vector2D(r*x, r*y);}//向量点积public double dot(Vector2D vector2D) {return vector2D.x*this.x+vector2D.y*this.y;}//获得单位化向量public Vector2D normal() {return new Vector2D(x/model, y/model);}//求垂直向量public Vector2D perp() {return new Vector2D(-y,x);}//向量旋转public Vector2D roatation(double theta) {double temp = x*Math.cos(theta)-y*Math.sin(theta);double newY = x*Math.sin(theta)+y*Math.cos(theta);return new Vector2D(temp, newY);}public String toString() {return String.format("("+x+","+y+")");}
}

        2.Actor类

package actor;import java.awt.*;
import Vector2D.Vector2D;public class Actor {public double mass;                //质量public Point position;             //点位置public Vector2D acceleration;       //加速度public Vector2D vector;               //速度public Vector2D displacement;        //位移public Vector2D force;                //受力public Actor(double mass,Point position) {this.mass = mass;this.position = position;}public void drawActor(Graphics g,int height,int width) {g.fillOval(position.x-width/2, position.y-height/2,height, width);}
}

3.Univers类

package univers;import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.datatransfer.SystemFlavorMap;
import javax.swing.JPanel;
import Vector2D.Vector2D;
import actor.Actor;public class Univers extends JPanel implements Runnable{private static double G = 6.67E-11;                        //万有引力常数private Point[] star = new Point[500];                     //背景的星星private Point origSun = new Point(319,239);                //太阳的位置private Point origEarth = new Point(469,239);              //地球的初始位置private Point origVenus = new Point(429,239);              //金星的初始位置private Point origMercury = new Point(378,239);            //水星的初始位置private Actor sun = new Actor(2E30,origSun);               //太阳private Actor earth = new Actor(6E24,origEarth);           //地球private Actor venus = new Actor(4.9E24, origVenus);        //金星private Actor mercury = new Actor(3.3E23, origMercury);    //水星private Vector2D earthPosition = new Vector2D(origSun,origEarth);     //地球的位置向量private	Vector2D venusPosition = new Vector2D(origSun, origVenus);    //金星的位置向量private	Vector2D mercuryPosition = new Vector2D(origSun, origMercury);//水星的位置向量        private Vector2D vectorEarth = new Vector2D(0, 3E4);        //地球当前速度private Vector2D vectorVenus = new Vector2D(0, -3.5E4);     //金星当前速度private Vector2D vectorMercury = new Vector2D(0,4.8E4);     //水星当前速度private long time = 1;public Univers2() {for(int i=0;i<500;i++) {int x=(int) (Math.random()*640);int y=(int) (Math.random()*480);star[i] = new Point(x,y);}}private void calculate() {mercuryCalculate();venusCalculate();earthCalculate();}//地球轨道的计算private void earthCalculate() {Vector2D delta_displacement = vectorEarth.multi(time*1e-9); //乘1e9是对长度缩放earthPosition = earthPosition.plus(delta_displacement);double current_acceleration = G*2.0e30/(earthPosition.getModel()*earthPosition.getModel()*1e18);earth.acceleration = earthPosition.normal().multi(-current_acceleration);vectorEarth = vectorEarth.plus(earth.acceleration.multi(time));}//金星轨道的计算private void venusCalculate() {Vector2D delta_displacement = vectorVenus.multi(time*1e-9); //乘1e9是对长度缩放venusPosition = venusPosition.plus(delta_displacement);double current_acceleration = G*2.0e30/(venusPosition.getModel()*venusPosition.getModel()*1e18);venus.acceleration = venusPosition.normal().multi(-current_acceleration);vectorVenus = vectorVenus.plus(venus.acceleration.multi(time));}//水星轨道的计算private void mercuryCalculate() {Vector2D delta_displacement = vectorMercury.multi(time*1e-9); //乘1e9是对长度缩放mercuryPosition = mercuryPosition.plus(delta_displacement);double current_acceleration = G*2.0e30/(mercuryPosition.getModel()*mercuryPosition.getModel()*1e18);mercury.acceleration = mercuryPosition.normal().multi(-current_acceleration);vectorMercury = vectorMercury.plus(mercury.acceleration.multi(time));}//绘制所有行星@Overridepublic void paint(Graphics g) {// TODO 自动生成的方法存根super.paint(g);for(int i=0;i<500;i++) {                //让背景闪烁g.setColor(Color.white);if(Math.random()>0.5) {g.setColor(Color.gray);}g.fillOval(star[i].x,star[i].y,2,2);}g.setColor(Color.red);sun.drawActor(g,30,30);g.setColor(Color.gray);g.fillOval((int)(origSun.x+mercuryPosition.getX()-1),(int)(origSun.y-mercuryPosition.getY()-1), 6, 6);g.setColor(Color.yellow);g.fillOval((int)(origSun.x+venusPosition.getX()-1),(int)(origSun.y-venusPosition.getY()-1), 6,6);g.setColor(Color.blue);g.fillOval((int)(origSun.x+earthPosition.getX()-1), (int)(origSun.y-earthPosition.getY()-1),6, 6);}@Overridepublic void run() {// TODO 自动生成的方法存根setBackground(Color.black);while(true) {repaint();calculate();time += 100;        //数字可以随便填try {Thread.sleep(1);} catch (InterruptedException e) {// TODO 自动生成的 catch 块e.printStackTrace();}}}
}

        4.Main类

package main;import java.awt.Container;
import javax.swing.JFrame;
import univers.Univers;
import univers.Univers;public class Main extends JFrame{private Univers univers = new Univers();private Container container = getContentPane();private Thread renderThread = new Thread(univers);public Main() {setTitle("行星运动");setSize(640,480);setDefaultCloseOperation(EXIT_ON_CLOSE);container.add(univers);setVisible(true);renderThread.start();}public static void main(String[] args) {// TODO 自动生成的方法存根new Main();}}

三、运行结果

灰色的为水星,黄色的为金星,蓝色的为地球,红色是太阳。

        

下篇文章来写三体运动的模拟。自学Java会遇到很多问题,如有问题还请多多指正。


http://chatgpt.dhexx.cn/article/yaGdX4Yp.shtml

相关文章

java课程设计旋转的行星_Java编程实现的模拟行星运动示例

本文实例讲述了Java编程实现的模拟行星运动。分享给大家供大家参考&#xff0c;具体如下&#xff1a; 期待了很久的Java语言程序设计也拉下了帷幕&#xff0c;在几个月的时间里基本掌握了java的简单用法&#xff0c;学习了java的主要基础知识&#xff0c;面向对象思想&#xff…

JS-圆,椭圆等轨迹相关算法

圆 公式 (x0, y0) 圆心坐标 r&#xff1a;半径 x x0 cos(angle) * r y y0 sin(angle) * r 1、轨迹 <div id"div" style"position:relative; width: 20px; height: 20px; background: cadetblue;"></div><script>/*** 圆心 (x0, y0…

精确绘制椭圆

本文首发于微信公众号「3D视觉工坊」。 前言 圆特征在测量领域中应用广泛&#xff0c;比如&#xff1a;相机标定、位姿估计、目标跟踪等方面。圆经过透视投影&#xff0c;当成像平面与圆平面不平行时&#xff0c;圆经过透视投影为椭圆&#xff0c;圆心的透视投影点与椭圆的中…

cesium椭圆编辑椭圆修改(cesium篇.78)

听老人家说:多看美女会长寿 地图之家总目录(订阅之前必须先查看该博客) 完整代码工程包下载 运行如有问题,可“私信”博主。效果如下所示: 下面献上完整代码,代码重要位置会做相应解释 <html lang="en

JS小球绕着椭圆形的轨迹旋转并且近大远小

在ivx中案例如下&#xff1a; VxEditor 效果如下&#xff0c;近大远小 主要代码如下&#xff1a; const centerX 360 / 2; // 椭圆中心的X坐标 const centerY 120 / 2; // 椭圆中心的Y坐标 const a 100; // 长半轴 const b 60; // 短半轴const elementsWithClassName d…

知识图谱实战应用2-知识图谱的知识融合与知识消歧

大家好,我是微学AI,今天给大家带来知识图谱实战应用2-知识图谱的知识融合与知识消歧。 知识图谱是用于表示语义化信息的一种图形化知识表示形式,其中包含了大量的实体、属性和关系。由于知识图谱是由不同来源的知识组成的,因此可能存在同一实体在不同知识源中有不同的表达…

【知识图谱】深入浅出讲解知识图谱(技术、构建、应用)

本文收录于《深入浅出讲解自然语言处理》专栏&#xff0c;此专栏聚焦于自然语言处理领域的各大经典算法&#xff0c;将持续更新&#xff0c;欢迎大家订阅&#xff01;个人主页&#xff1a;有梦想的程序星空个人介绍&#xff1a;小编是人工智能领域硕士&#xff0c;全栈工程师&a…

知识图谱从入门到应用——知识图谱的知识表示:符号表示方法

分类目录&#xff1a;《知识图谱从入门到应用》总目录 相关文章&#xff1a; 知识图谱的知识表示&#xff1a;基础知识 知识图谱的知识表示&#xff1a;符号表示方法 知识图谱的知识表示&#xff1a;向量表示方法 在前面的文章中已经多次提到&#xff0c;知识图谱采用图的方…

《什么是知识图谱?为什么需要知识图谱?知识图谱有什么应用? - 翔哥带你初识知识图谱》

原创实在不易&#xff0c;欢迎大家关注我微信公众号&#xff1a;阳洋up 我本人主要是做知识图谱表示学习研究的&#xff0c;通过读取大量CCF顶会论文以及与导师的交流沟通&#xff0c;逐渐形成了对知识图谱的大的层面上的一些认知&#xff0c;希望在CSDN平台上分享我的一些学习…

知识图谱从入门到应用——知识图谱的知识表示:向量表示方法

分类目录&#xff1a;《知识图谱从入门到应用》总目录 相关文章&#xff1a; 知识图谱的知识表示&#xff1a;基础知识 知识图谱的知识表示&#xff1a;符号表示方法 知识图谱的知识表示&#xff1a;向量表示方法 前文已经介绍过&#xff0c;向量化的表示已经在人工智能的其…

知识图谱|知识图谱的典型应用

作者&#xff1a; cooldream2009 我们构建知识图谱的目的&#xff0c;在于利用知识图谱来做一些事情。有效利用知识图谱&#xff0c;就是要考虑知识图谱的具备的能力&#xff0c;知识图谱具有哪些能力呢&#xff0c;首先我们知道知识图谱包含了海量的数据&#xff0c;是一个超…

知识图谱入门知识(一)知识图谱应用以及常用方法概述

学习内容 搜集各种博客&#xff0c;理解实体识别、关系分类、关系抽取、实体链指、知识推理等&#xff0c;并且总结各种分类中最常用的方法、思路。 由于自己刚刚接触知识图谱&#xff0c;对该领域的概念和方法的描述还不是很清楚&#xff0c;所以只是简单的列出框架和添加链接…

时空知识图谱应用初探

一、时空知识图谱概述 时空知识图谱不单单是一个“增强型”的开放域知识图谱&#xff0c;而是需要结合业务场景和领域知识&#xff0c;并针对时空知识自身的特点&#xff0c;对知识的概念、实体和关系进行语义化和时空化拓展。时空知识图谱除了描述语义关系外&#xff0c;还需要…

【知识图谱】知识图谱应用

知识图谱怎么用 知识图谱应用场景 辅助搜索——精准回答 eg&#xff1a; 辅助问答——人机互动 eg&#xff1a; 辅助数据集成——智能数据整合 eg&#xff1a; 辅助决策——智能决策 知识图谱和各种AI技术综合使用能更好地发挥AI的作用 eg&#xff1a;wbq为什么选择张…

知识图谱从入门到应用——知识图谱的知识表示:基础知识

分类目录&#xff1a;《知识图谱从入门到应用》总目录 相关文章&#xff1a; 知识图谱的知识表示&#xff1a;基础知识 知识图谱的知识表示&#xff1a;符号表示方法 知识图谱的知识表示&#xff1a;向量表示方法 知识表示是人工智能领域一个较为核心的问题。对于知识表示的…

知识图谱从入门到应用——知识图谱的技术结构

分类目录&#xff1a;《知识图谱从入门到应用》总目录 相关文章&#xff1a; 知识图谱的基础知识 知识图谱的发展 知识图谱的应用 知识图谱的技术结构 知识图谱是交叉技术领域 知识图谱是典型的交叉技术领域。在人工智能和机器学习领域&#xff0c;传统符号知识表示是知识…

知识图谱从入门到应用——知识图谱的发展

分类目录&#xff1a;《知识图谱从入门到应用》总目录 相关文章&#xff1a; 知识图谱的基础知识 知识图谱的发展 知识图谱的应用 知识图谱的技术结构 1945年&#xff0c;美国首任总统科学顾问Vannevar Bush曾提出了一个称为MEMEX的“记忆机器”的设想。他认为人的记忆偏重…

知识图谱从入门到应用——知识图谱的基础知识

分类目录&#xff1a;《知识图谱从入门到应用》总目录 相关文章&#xff1a; 知识图谱的基础知识 知识图谱的发展 知识图谱的应用 知识图谱的技术结构 知识图谱是有学识的人工智能 早期的人工智能有很多持不同观点的流派&#xff0c;其中两个历史比较悠久的流派通常被称为…

知识图谱的应用领域

1.3 知识图谱的价值 知识图谱最早的应用是提升搜索引擎的能力。随后&#xff0c;知识图谱在辅助智能问答、自然语言理解、大数据分析、推荐计算、物联网设备互联、可解释性人工智能等多个方面展现出丰富的应用价值。 1.辅助搜索 互联网的终极形态是万物的互联&#xff0c;而…

最详细的知识图谱的技术与应用

导读&#xff1a;从一开始的Google搜索&#xff0c;到现在的聊天机器人、大数据风控、证券投资、智能医疗、自适应教育、推荐系统&#xff0c;无一不跟知识图谱相关。它在技术领域的热度也在逐年上升。 本文以通俗易懂的方式来讲解知识图谱相关的知识、尤其对从零开始搭建知识图…