Advertisement

太阳系行星运行图-java多媒体实验

阅读量:

开发一个具有多线程功能的程序,在该程序中将分别赋予地球和其他每个行星各自独立运行的一个线程。设定参数d后,每个天体将按照自身实际速度乘以d的比例进行运动。在该模型中,默认认为太阳处于静止状态。因此,在计算其他天体的速度时,默认将以太阳为中心参考系。为了使模型直观易懂且具有视觉吸引力,在确定各天体与太阳的距离时,默认采用适当缩放的比例。

假设中心(0,0),x=rcosθ,y=rsinθ,用角速度计算更新位置。

通过等速率圆周运动来表示行星。八大行星包括水星、金星、地球、火星等。

每个行星都分配独立的线程用于计算其当前的角度值;太阳系绘制任务独立运行以完成场景渲染工作。整个系统总共运行了9个独立的线程以实现并行计算。

复制代码
  
    
 import java.awt.BorderLayout;
    
 import java.awt.Color;
    
 import java.awt.Container;
    
 import java.awt.Graphics;
    
 import java.awt.Image;
    
  
    
 import javax.swing.ImageIcon;
    
 import javax.swing.JFrame;
    
 import javax.swing.JPanel;
    
  
    
  
    
 //行星动画主窗口
    
 public class PlanetAnimation extends JFrame{
    
  
    
 	Data sharedData = new Data(); //构造数据对象,里面有行星数据,该对象传递给各个线程
    
 	ExclusiveData planetAngle=new ExclusiveData();//各个星球当前的角度
    
 	DrawPanel drawPanel;//绘制面板
    
 	starThread planetThread[]=new starThread[8];//每个行星一个线程,负责位置更新工作
    
 	DrawThread drawThread;//负责太阳系全部绘制工作的线程
    
 	int i,j;
    
 	public PlanetAnimation() {
    
 		super("太阳系行星图");
    
 		//下面布局界面
    
 		//构造绘制面板
    
 		drawPanel=new DrawPanel(sharedData,planetAngle);
    
 		Container c = getContentPane();
    
 		c.add(drawPanel,BorderLayout.CENTER);//画布放在中间
    
 		//加载宇宙背景
    
 		sharedData.backgraundImg=new ImageIcon("panel.jpg").getImage();
    
 		//下面构造8个行星的线程,并启动线程。每个线程计算行星的当前角度
    
 		for(i=0;i<8;i++) 
    
 		{
    
 			planetThread[i]=new starThread(sharedData,planetAngle,i);//每个行星的线程
    
 			planetThread[i].start();//启动行星线程
    
 		}
    
 		drawThread=new DrawThread(drawPanel);//创建太阳系绘制线程
    
 		drawThread.start();//启动太阳系绘制线程
    
 		
    
 	}
    
 	public static void main(String[] args) {
    
 		// TODO Auto-generated method stub
    
 		PlanetAnimation exp = new PlanetAnimation();//行星动画主窗口
    
 		exp.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
 		exp.setSize(exp.getMaximumSize());//最大化窗口
    
 		exp.setVisible(true);
    
 	}
    
 }
    
  
    
  
    
 //画布、该类负责场景绘制
    
 class DrawPanel extends JPanel
    
 {
    
 	int i,j,x,y;
    
 	int width,height;
    
 	Data shareddata; //行星数据
    
 	ExclusiveData angledata;//行星的当前角度
    
 	DrawPanel(Data data1,ExclusiveData data2)//传入行星数据及行星当前角度
    
 	{
    
 		shareddata=data1;
    
 		angledata=data2;
    
 	}
    
 	//绘制太阳系场景
    
 	void draw() 
    
 	{
    
 		shareddata.x0=this.getWidth()/2; //计算中心点(太阳)
    
 		shareddata.y0=this.getHeight()/2;
    
 		repaint(); //Java虚拟机内部调用paintComponent()方法实现绘制当前面板
    
 	}
    
 	
    
 	//真正绘制场景
    
 	protected void paintComponent(Graphics g)//重写父类方法
    
 	{
    
 		//清空并绘制背景
    
 		g.clearRect(0, 0, getWidth(), getHeight());//清空画布
    
 		g.drawImage(shareddata.backgraundImg, 0, 0, this.getWidth(), this.getHeight(), this);
    
 		//绘制宇宙背景
    
 		//画太阳
    
 		width=(int)shareddata.planeSize[8];//获取太阳直径
    
 		height=(int)shareddata.planeSize[8];
    
 		g.setColor(shareddata.color[8]);//取绘制太阳的颜色
    
 		g.fillOval(shareddata.x0-width/2,shareddata.y0-height/2, width, height);//画太阳
    
 		
    
 		//画各个行星的轨道
    
 		for(i=0;i<8;i++)//画8个行星轨道
    
 		{
    
 			g.setColor(shareddata.color[i]);//取轨道颜色
    
 			width=(int)(2*shareddata.radius[i]);//圆的宽高
    
 			height=(int)(2*shareddata.radius[i]);
    
 			//下面绘制轨道圆
    
 			g.drawOval(shareddata.x0-shareddata.radius[i], shareddata.y0-shareddata.radius[i], width, height);
    
 		}
    
 		//画八个行星
    
 		for(i=0;i<8;i++)
    
 		{
    
 			//该行星i当前位置(x,y)计算
    
 			int r = shareddata.radius[i]; //取当前行星距离太阳中心的距离
    
 			//下面计算行星当前坐标;当前坐标=太阳中心坐标+行星当前角度对应坐标偏移
    
 			//计算该行星中心的当前x坐标
    
 			x=shareddata.x0+(int)(r*Math.cos(angledata.angle[i]*Math.PI/180));
    
 			//计算该行星中心的当前y坐标
    
 			y=shareddata.y0+(int)(r*Math.sin(angledata.angle[i]*Math.PI/180));
    
 			g.setColor(shareddata.color[i]); //取行星绘制颜色
    
 			width=(int)shareddata.planeSize[i];//取行星直径
    
 			height=width;
    
 			g.fillOval(x-width/2, y-height/2, width, height);//绘制行星i
    
 			g.drawString(shareddata.name[i], x+width/2,y);//绘制行星的名字
    
 		}
    
 	}	
    
 }
    
  
    
 //八大行星的线程类
    
 class starThread extends Thread
    
 {
    
 	int id;
    
 	//行星编号:水星0,金星1,地球2,火星3,木星4,土星5,天王星6、海王星7
    
 	Data dataShared; //共享数据
    
 	ExclusiveData angleData;//行星当前角度
    
 	long lastTime,now;//上次时刻,当前时刻
    
 	
    
 	public starThread(Data data1,ExclusiveData data2,int i)
    
 	{
    
 		id=i; //八大行星各自的编号
    
 		dataShared=data1; //传入共享数据
    
 		angleData=data2; //传入行星当前角度
    
 	}
    
 	//八大行星的线程体,负责计算每个行星的当前角度(用角度表示)
    
 	public void run()//更新线程
    
 	{
    
 		lastTime=System.currentTimeMillis();//取当前时刻
    
 		while(true)//行星角度循环更新
    
 		{
    
 			now=System.currentTimeMillis();//返回当前的毫秒数
    
 			//下面计算当前行星id的当前角度:新的角度=原角度+(该行星角速度*上次到现在经历的时间长度)*速度影响因子
    
 			angleData.angle[id]=(angleData.angle[id]+dataShared.angleSpeed[id]*((now-lastTime)/100)*dataShared.d)%360;
    
 			lastTime=now;//保留当前时刻
    
 			try {
    
 				Thread.sleep(200);//每200毫秒更新行星角度
    
 				
    
 			}catch(InterruptedException e)
    
 			{
    
 				System.err.println("异常");
    
 			}
    
 		}//end of while
    
 	}
    
 }
    
  
    
  
    
 //太阳系绘制线程
    
 class DrawThread extends Thread
    
 {
    
 	DrawPanel drawPanel;//画布
    
 	DrawThread(DrawPanel Panel)
    
 	{
    
 		drawPanel=Panel; //保存绘制面板
    
 	}
    
 	//太阳系线程体:每隔100毫秒完成一次绘制
    
 	public void run() 
    
 	{
    
 		while(true)
    
 		{
    
 			drawPanel.draw();//绘制太阳系场景
    
 			try {
    
 				Thread.sleep(100);//每100毫秒更新行星角度
    
 				
    
 			}catch(InterruptedException e)
    
 			{
    
 				System.err.println("异常");
    
 			}
    
 		}
    
 	}
    
 	
    
 }
    
  
    
 //类对象包含有关行星的数据
    
 class Data
    
 {
    
 	Image backgraundImg; //背景图像
    
 	float d=5; //速度影响因子,模型以实际速度的d倍来行走
    
 	int x0,y0;//太阳中心
    
 	float radiusBase = 210; //用于调节绘制效果的半径调节因子
    
 	float sizeBase=5; //行星直径调节因子
    
 	float speedBase =1; //角速度调节因子
    
 	
    
 	////行星的公转周期(天):(与最快的水星比较的倍数)
    
 	//水星: 88(1) 金星: 225 (2.5)地球: 365 (4.1);火星: 687 (7.8)
    
 	//木星: 4333 (49) 土星10760: (122) 天王星:30799 (350) 海 王星: 60118 (683)
    
 	//下面计算:每个行星的角速度=每天转动的角度*角速度调节因子=(360 度/公转周期天数)*角速度调节因子
    
 	
    
 	float[] angleSpeed= {360/88f*speedBase,360/225f*speedBase,360/365f*speedBase,360/687f*speedBase,360/4333f*speedBase,360/10760f*speedBase,360/30799f*speedBase,360/60118f*speedBase};
    
 	//顺序0~7:水星,金星,地球,火星,木星,土星,天王星,海王星
    
 	//各个行星的实际直径:(与最小的木星相比的倍数)
    
 	//水星: 49.532千公里(10) 金星: 12.104千公里(2.5)
    
 	//地球:12.756千公里(3) 火星: 6.796千公里(1.4)
    
 	//木星: 4.88千公里(1) 土星: 120.536千公里(25) 天
    
 	//王星: 51.8千公里(10) 海王星: 49.532千公里(10)
    
 	////太阳: 1392千公里(284)
    
 	//下面计算每个行星的直径:行星直径=(行星直径/最小木星的直径)*行星 直径调节因子
    
 	double planeSize[]= {49.5/4.9*sizeBase,12.1/4.9*sizeBase,12.7/4.9*sizeBase,6.7/4.9*sizeBase,4.9/4.9*sizeBase,120.5/4.9*sizeBase,51.8/4.9*sizeBase,49.5/4.9*sizeBase,220/4.9*sizeBase};
    
 	
    
 	//顺序0~8:水星,金星,地球,火星,木星,土星,天王星、海王星,太阳
    
 	//各个行星的公转半径(亿公里): (与最近的水星比的倍数) 
    
 	//水星:0.5791 (1) 金星: 1.082 (2) 地球: 1.496 (3) 火星: 2.2794 (4)
    
 	////木星: 7.7833 (13) 土星: 14.294 (24.5) 天王星: 28.7668(50) 海王星: 45.04 (77.5)
    
 	//下面计算每个行星距离太阳中心的半径:行星的绘制半径=行星半径*半径调节因子
    
 	
    
 	int radius[]= {(int)(0.57*radiusBase),(int)(1.08*radiusBase),(int)(1.2*radiusBase),(int)(1.5*radiusBase),(int)(1.8*radiusBase),(int)(2.0*radiusBase),(int)(2.2*radiusBase),(int)(2.4*radiusBase)};
    
 	
    
 	Color color []= {Color.magenta,Color.YELLOW, Color.blue, Color.red, Color.cyan, Color. pink, Color. BLACK, Color. white, Color.red};
    
 	String name []= {"水星","金星","地球","火星","木星","土星","天王星","海王星","太阳"};
    
 	//各个行星的最新角度
    
 }
    
  
    
 //各个行星的最新角度
    
 class ExclusiveData{
    
 	//下面是每个行星当前角度。由startThread线程更新。
    
 	double angle[]= {0f,0f,0f,0f,0f,0f,0f,0f};
    
 	//顺序0~7:水星,金星,地球,火星,木星,土星,天王星、海王星
    
 	
    
 }
    
  
    
    
    
    
    
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-07-14/IVg60vXteJCZLWF24Tzp3mqScM5D.png)

全部评论 (0)

还没有任何评论哟~