Virtual Solar System in Jave3D and Swing

  • (2 Pages)
  • +
  • 1
  • 2

24 Replies - 8921 Views - Last Post: 05 August 2013 - 10:47 PM

#1 PGR  Icon User is offline

  • D.I.C Head

Reputation: 13
  • View blog
  • Posts: 55
  • Joined: 10-January 11

Virtual Solar System in Jave3D and Swing

Posted 23 June 2013 - 06:35 PM

I'm trying to make a virtual solar system in Java3D and Swing. The idea is is to have objects (masses) interact by way of gravity. So, everything has its own position, speed (vector), rotation and rotation speed. Things should orbit Ė the earth around the sun, the moon around the earth and a ship around the Earth Ė on their own.

There will be a number of different ships. One will go light speed so you can zip around the solar system.

One problem is that to have precise control over the speed I made the smallest increment of space to be one meter (yard). This really pushes the limits of the doubles. And if Java3D only takes floats, then the doubles are worthless. (You canít pour a bucket of water into a thimble and not lose most of the water.) I may have to convert to kilometers.

The Mass3D class is a GroupTransform. This allows me to add a camera to a ship. And, the multi-state rocket will have each part added to the child of the top part. So, the nose cone adds the 3rd stage, the 3rd stage adds the 2nd stage, the 2nd stage adds the 1st stage.

There will be a Ďselectedí variable which will hold the currently selected object. Then you can drive a ship or a camera. Planets wonít have fuel so you canít fly them. If two objects touch, they dock and ignore the effects of gravity on each other. Iíd like to add rotational velocity to the ship on earth so that it moves to the same spot on the rotating earth.

The upper right of Mission Control will have monitors with views from different cameras. I have a readout panel Iíll add tomorrow to display the currently selected objects stats.

So, Iíll upload the files. I simplified my MissionControl class and called the new one Houston - when I get more parts added, I'll rename it back to MissionControl. Also, I'm saying, I hope I included all the files. The uploader wouldn't let me upload whole files.

Mass3D
Vector3D
Houston
Percentagelayout

Any help will be appreciated. I need someone who is good in trig and calc to take vectors and the speed and calculate the movement of the planets and ships. In another 3D lib I have (Shout3D Ė itís on Amazon) they use frames per second to divide the speed of the ship up over time (a second). View has the current frame but, not the frames per second but it can be calculated.

Iím actually at a loss as to how to set an objects location to something other than 0,0,0. Iíll have to find an example that I understand.

pgr

/**
 *
 * @author Owner
 */

//package houston;
import java.awt.*;		//Graphics, Color
import javax.media.j3d.*;
import javax.vecmath.*;
import javax.swing.*;
import javax.swing.table.*;
import com.sun.j3d.utils.geometry.*;
import com.sun.j3d.utils.universe.*;
import com.sun.j3d.utils.universe.SimpleUniverse;



public class Houston extends JApplet{

public static final double KILO = 1000;

	private javax.swing.JPanel drawingPanel;//do not modify
	SimpleUniverse uni;
	BranchGroup group;
	Canvas3D	view;

//									name, mass, radius, dist (x,z), x, y, z, xv, yv, zv, xr, yr, zr, xrv, yrv, zrv, color
	Object[][]			myMass = {
									{"Sun",     "1.99e+9", "5.59648e+11",           "0", "0",           "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0"}//,
									//{"Earth", 5973.6e21, 1.49669e+11,     6371000, 0,           0, 0, 0, 0, 0, 0, 0, 0, 0, 0, new Color(255, 255, 0)},
									//{"Moon",   7.371e22,  17371*KILO, 1.49669E+11, 0, 384403*KILO, 0, 0, 0, 0, 0, 0, 0, 0, 0, new Color(255, 255, 0)},
	};


	/**
	 * @param args the command line arguments
	 */
	public static void main(String[] args) {
		System.out.println("Mission Control");
		JFrame mainFrame = new JFrame("Mission Control");
		JFrame.setDefaultLookAndFeelDecorated(true);
		mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		mainFrame.setBounds(100, 100, 4 * 200, 3 * 200);
		Houston theProgram = new Houston();
		theProgram.init();
		theProgram.start();
		mainFrame.getContentPane().add("Center", theProgram);
		mainFrame.setVisible(true);

	}
	
	
	Houston(){
		setMinimumSize(new Dimension(100, 100));
		setVisible(true);
	}


	public void init(){

		//setup uni and group, add viewing window.  add components in initGUI
		try {
			SwingUtilities.invokeAndWait(new Runnable(){
				public void run(){
					initGUI();
				}

			});
		}
		catch (Exception e){
			System.out.println("MissionControl.init() Error: " + e);
			e.printStackTrace();
			//Thread.dumpStack();
			//System.exit(1);
		}
	}

	public void initGUI(){
		System.out.println("initGUI");
		setLayout(new PercentageLayout(2, 2, new int[]{75, 25}, new int[]{75, 25}));//2, 2, new int[]{75, 25}, new int[]{75, 25}
		
		//build 3D viewing panel
		GraphicsConfiguration config = SimpleUniverse.getPreferredConfiguration();
		view = new Canvas3D(config);
		view.setMinimumSize(new Dimension(10, 10));
		view.setVisible(true);
		getContentPane().add(view, "0");

		uni = new SimpleUniverse(view);
		uni.getViewingPlatform().setNominalViewingTransform();
		uni.getViewer().getView().setMinimumFrameCycleTime(5);
		

		//build 3D stuff
		group = new BranchGroup();
		//uni.addBranchGraph(group);//but must be done at end of init
		
		for (int i = 0; i < myMass.length;i++){
			group.addChild(getMass(i));
		}
		
		
		//add objects
		//Color3f color = new Color3f(12, 12, 10);//grey
		//Color3f color = new Color3f(10, 5, 0);/orange
		Color3f color = new Color3f(0,120, 0);//orange
		Vector3f direction = new Vector3f(10, 0, 0);
		DirectionalLight light = new DirectionalLight(color, direction);
		BoundingSphere bounds = new BoundingSphere(new Point3d(0,0,0), 100);
		light.setInfluencingBounds(bounds);
		group.addChild(light);

		Sphere ball = new Sphere(0.5f);
//		group.addChild(ball);

		//add 3D stuff
		//add editable
		//TransformGroup objTrans = new TransformGroup();
		//objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
		//group.addChild(objTrans);
		
		//create new behavior node (rotatable, movable)
		//Transform3D yAxis = new Transform3D();
		//Alpha rotationalAlpha = new Alpha(-1, 4000);
		//RotationInterpolator rotator = new RotationInterpolator(rotationalAlpha, objTrans, yAxis, 0.0f, (float) Math.PI*2.0f);
		//BoundingSphere spBounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 100.0);
		//rotator.setSchedulingBounds(spBounds);
		//group.addChild(rotator);
		
		//add group to view panel
		uni.addBranchGraph(group);

		

		

/*
		System.out.println("color=" + color);
		System.out.println("ball=" + ball);
		System.out.println("direction=" + direction);
		System.out.println("bounds=" + bounds);
		System.out.println("group=" + group);
		System.out.println("uni=" + uni);
*/
	}
	
	
	public Color getMyColor(int i){
		Color c = Color.PINK;
		switch(i){
			case 0:
				c = new Color(1, 1, 0);
				break;
			default:
				System.out.println("bad color index (" + i + ")");
				break;
		}
		return(c);
	}
	
	public TransformGroup getMass(int i){
		//Node node;
		
		//name/type, mass, diameter, location, velocity, rotation, rotation vector, scale, lenght
		TransformGroup tGroup = new TransformGroup();
		Transform3D tTrans;
		Appearance tApp;
		ColoringAttributes ca;
		String col;
		Shape3D tShape;
		Sphere tSphere;
		Geometry	tGeo;
		Mass tMass3D;
		//node = new Node();
		switch (i){
			case 0://sun
				tGroup = new Mass3D((String)myMass[i][0],
						Double.valueOf((String)myMass[i][1]),
						Double.valueOf((String)myMass[i][2]),
						(Vector3D)new Vector3D(Double.valueOf((String)myMass[i][3]), Double.valueOf((String)myMass[i][4]),Double.valueOf((String)myMass[i][5])),
						(Vector3D)new Vector3D(Double.valueOf((String)myMass[i][6]), Double.valueOf((String)myMass[i][7]),Double.valueOf((String)myMass[i][8])),
						(Vector3D)new Vector3D(Double.valueOf((String)myMass[i][9]), Double.valueOf((String)myMass[i][10]),Double.valueOf((String)myMass[i][11])),
						(Vector3D)new Vector3D(Double.valueOf((String)myMass[i][12]), Double.valueOf((String)myMass[i][13]),Double.valueOf((String)myMass[i][14]))
						
						//Sphere a = new Sphere();
						);

				ca = new ColoringAttributes();
				ca.setColor(new Color3f(1, 1, 0));
				tApp = new Appearance();
				tApp.setColoringAttributes(ca);
				//PolygonAttributes.setBackFaceNormalFlip();
				//tApp.setRenderingAttributes(RenderingAttributes.);
				tGroup.addChild(new Sphere(0.5f, tApp));
				
				//tTrans = new Transform3D();
				tGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
				tGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
				tTrans = new Transform3D();
				Alpha rotationAlpha = new Alpha(-1, 40);
				RotationInterpolator rotator = new RotationInterpolator(rotationAlpha, tGroup, tTrans, 0.0f, (float)Math.PI*2.0f);
				BoundingSphere bounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 100.0);
				rotator.setSchedulingBounds(bounds);
				
				
				
			break;

			default:
				System.out.println("getMass object " + i + " not found.  Ooops!");
				break;
		}
		return(tGroup);
	}


	public void start(){

	}




}


/*
 * 					float rotationDelta = -(dragDistanceX/60f);
					//eulers[controlled][Z] = eulers[controlled][Z] + rotationDelta;
					eulers[controlled][Z] = Math3D.addRadians(eulers[controlled][Z], rotationDelta);


 */


/**
 * Mass3D
 * @author Owner
 */

import java.awt.Color;
import java.awt.Graphics;
import java.util.ArrayList;
import javax.media.j3d.Shape3D;
import javax.media.j3d.TransformGroup;
import com.sun.j3d.utils.geometry.*;
//only 2D

class Mass3D extends TransformGroup{
	String		name;
	double		mass;//weight
	double		radius;//radius
	double		height;
	Vector3D	location;
	Vector3D	velocity;
	Vector3D	rotation;
	Vector3D	rotvel;
	Vector3D	tvec;
	Boolean		docked = false;//ignore effect of gravity with docked object
	ArrayList	host;//where am i docked

	Mass3D(){
			//this("blank", );
		}
	
	Mass3D(String name, double mass, double radius, Vector3D location, Vector3D velocity, Vector3D rotation, Vector3D rotvel){
		this.name = name;
		this.mass = mass;
		this.radius = radius;
		this.location = location; 
		this.velocity = velocity; 
		this.rotation = rotation;
		this.rotvel = rotvel;
		host = new ArrayList();
		//System.out.println(name + " [x =" + location.x + ",y =" + location.y + ",z =" + location.z + "]");
	}
	
	
	public double getMassHeight(){
		Mass3D tg;
		double h;
		if (numChildren() > 0){
			tg = (Mass3D)getChild(1);
			h = height + tg.getMassHeight();
		}
		else{
			h = height;
		}
		return(h);
	}
	
	
	public Vector3D getCenter(){//a rocket, like a boat, pivits on the nosecone/bow - center is halfway to end
		Vector3D v = location;
		//try{
		//	if (getChild(0).getGeometry().getClass() == Class.forName("Sphere")){
		//		v = location;
		//	}
		//	else{//find height/2
		//		v = location;
		//	}
		//}
		//catch(ClassNotFoundException e){
		//	System.out.println("Error: " + e);
		//	System.exit(0);
		//}
		return(v);
	}


	public double distance(Mass3D m){//to center
		Vector3D m1c;
		Vector3D m2c;
		
		m1c = getCenter();
		m2c =  m.getCenter();
		return (Math.sqrt(sq(m1c.x - m2c.x) + sq(m1c.y - m2c.y) + sq(m1c.z - m2c.z)));
	}
	
	//x2 = x1 + (Math.cos(Math.toRadians(rotation.x)) * (length));// * scale
	//y2 = y1 + (Math.sin(Math.toRadians(rotation.x)) * (length));// * scale
	public double altitude(Mass3D m){//to serface (dist - radii)
		return (distance(m) - (radius + m.radius));
	}
	
	//F = G((m1*m2)/r^2))
	public void rotate(){
		tvec.setVector(rotvel.x, rotvel.y, rotvel.z);
		rotation.addVector(tvec);
	}

	public void addPos(Mass3D m){
		tvec = new Vector3D(velocity.x, velocity.y, velocity.z);
		location.addVector(tvec);

		if (altitude(m) < 5){
			if (!isDockedWith(m)){
				dockWith(m);
				System.out.println(name + " is docking with " + m.name + " at " +  (int)altitude(m) + "m");
			}
		}
		else{
			if (isDockedWith(m)){
				undockFrom(m);
				System.out.println(name + " is undocking from " + m.name + " at " +  (int)altitude(m) + "m");
			}
		}
	}
	
	
	//F = G((m1*m2)/r^2)
	public double fOG(Mass3D m){
		return(MissionControl.G * ((mass * m.mass)/Math.sqrt(sq(location.x - m.location.x) * sq(location.y - m.location.y) * sq(location.z - m.location.z))));
	}
	
	public double sq(double d){
		return (d * d);
	}

	
	//accel from gravity
	public void accelerate(Mass3D m){//change in velocity
		double theta;
		double dx, dy, dz;
		double txv;
		double tyv;
		double tzv;
		
		//F = G((m1*m2)/r^2))
		//x2 = x1 + (Math.cos(Math.toRadians(rotation.x)) * (length));// * scale
		//y2 = y1 + (Math.sin(Math.toRadians(rotation.x)) * (length));// * scale
		if (!isDockedWith(m)){
			theta = Math.atan2(m.location.x - location.x, m.location.y - location.y);
			System.out.println("acc: " + name + " cos=" + (int)Math.cos(Math.toRadians(theta)) + ", sin=" + (int)Math.sin(Math.toRadians(theta)) + ", fOGX=" + (int)fOG(m));
			txv =  Math.cos(Math.toRadians(theta)) * fOG(m);//
			tyv = -Math.sin(Math.toRadians(theta)) * fOG(m);//
			tzv =  0d;//Math.cos(Math.toRadians(rotation.z)) * 9.8;
			System.out.println(name + " [txv=" + txv + ",tyv=" + tyv + ",tzv=" + tzv + "]");
			tvec.setVector(txv, tyv, tzv);
			//tvec.divVector(timestep);//div 1000 ms by 1, 10, 100, 1000
			velocity.addVector(tvec);
		}
		else{
			//System.out.println(name + " docked with " + m.name + " at " + altitude(m));
		}
	}

	
	public void move(Mass3D m){//drive like space ship
		rotate();		
		accelerate(m);	//from gravity
		//addThrust();
		addPos(m);
	}


	public void addThrust(){
		System.out.println("Mass.addThrust()");
		//do nothing
	}
	
	public void subtractThrust(){
		//do nothing
	}
	
	public void turnRight(){
		//do nothing
	}
	
	public void turnLeft(){
		//do nothing
	}
	
	public void dockWith(Mass3D m){
		if (host.contains(m)){
			//still docked
		}
		else{
			System.out.println(name + " is docking with " + m.name);
			host.add(m);
		}
	}
	
	public void undockFrom(Mass3D m){
		if (host.contains(m)){
			System.out.println(name + " is undocking with " + m.name);
			host.remove(m);
		}
		else{
			//still undocked
		}
	}
	
	
	public boolean isDockedWith(Mass3D m){
		
		return (host.contains(m));
	}
	
	@Override
	public String toString(){
		return(new String(name + " [(x =" + (int)location.x + ",y =" + (int)location.y + ",z =" + (int)location.z + "),(xv=" + (int)velocity.x + ",yv=" + (int)velocity.y + ",zv=" + (int)velocity.z + ")]"));
	}
	
}


//PercentageLayout.java
//by Peter Ruffner

//package

//Thank you SGLayout for the original code
//http://www.docjar.com/docs/api/au/com/pegasustech/demos/layout/SGLayout.html
//(au.com.pegasustech.demos.layout)
//http://www.javaworld.com/javatips/jw-javatip129.html

import java.awt.*;
import java.applet.*;

//example
//PercentageLayout(2, 3, new int[] {33, 67}, new int[] {33, 34, 33}, true);//rows, cols
//number of rows
//number of columns
//array with int values for rows
//array with int values for columns
//debugging

//use the line below in app to add to frame/panel
//int i = 1;
//add(np, Integer.toString(i));

public class PercentageLayout implements LayoutManager
{
	//int nrowCount, ncolCount;
	float[]	rowPercent;
	float[]	colPercent;
	int[]	rowDim;
	int[]	colDim;
	int[]	rowDif;
	int[]	colDif;
	int		left =0,top =0, right =0, bottom =0;	//insets
	protected int rowCount, colCount, hgap, vgap, hratio, vratio;
	int layoutMode = 0;
	Component[] myComps;
	Boolean debugging = false;

	PercentageLayout()
	{
		this(2, 2, new int[] {25, 75}, new int[] {25, 75}, 0, 0, 0, 0, false);
	}

	PercentageLayout(Boolean B)/>/>
	{
		this(2, 2, new int[] {25, 75}, new int[] {25, 75}, 0, 0, 0, 0, B)/>/>;
	}


	PercentageLayout(int rowCount, int colCount, int[] rowPercent, int[] colPercent)
	{
		this(rowCount, colCount, rowPercent, colPercent, 0, 0, 0, 0, false);
	}


	PercentageLayout(int rowCount, int colCount, int[] rowPercent, int[] colPercent, Boolean B)/>/>
	{
		this(rowCount, colCount, rowPercent, colPercent, 0, 0, 0, 0, B)/>/>;
	}


	PercentageLayout(int rowCount, int colCount, int[] rowPercent, int[] colPercent, int hgap, int vgap)
	{
		this(rowCount, colCount, rowPercent, colPercent, hgap, vgap, 0, 0, false);
	}


	PercentageLayout(int rowCount, int colCount, int[] rowPercent, int[] colPercent, int hgap, int vgap, Boolean B)/>/>
	{
		this(rowCount, colCount, rowPercent, colPercent, hgap, vgap, 0, 0, B)/>/>;
	}


	PercentageLayout(int rowCount, int colCount, int[] rowPercent, int[] colPercent, int hgap, int vgap, int hratio, int vratio)
	{
		this(rowCount, colCount, rowPercent, colPercent, hgap, vgap, 0, 0, false);
	}


	//main constructor
	PercentageLayout(int rowCount, int colCount, int[] rowPercent, int[] colPercent, int hgap, int vgap, int hratio, int vratio, Boolean B)/>/>
	{
		int n = 0;
		//System.out.println("Construction PercentageLayout");
		debugging = b;
		this.rowCount = rowCount;
		this.colCount = colCount;

		n = rowCount * colCount;
		if (n == 0)//must have at least 1 space
		{
			if (debugging) System.out.println("Error: must have at least 1 panel");
		}
		
		myComps = new Component[rowCount * colCount];

		//save row/col data
		//convert from percent to pixles in setMaxDims()
		this.rowPercent = new float[rowCount];
		rowDim = new int[rowCount];
		rowDif = new int[rowCount];
		for (int i = 0;i < rowCount;i++)
		{
			this.rowPercent[i] = ((float)rowPercent[i]) * 0.01f;
			if (debugging) System.out.println("rowPercent[" + i + "] = " + this.rowPercent[i]);
		}

		this.colPercent = new float[colCount];
		colDim = new int [colCount];
		colDif = new int [colCount];
		for (int i = 0;i < colCount;i++)
		{
			this.colPercent[i] = ((float)colPercent[i]) * 0.01f;
			if (debugging) System.out.println("colPercent[" + i + "] = " + this.colPercent[i]);
		}
		if (debugging) System.out.println();

		this.hgap = hgap;
		this.vgap = vgap;
		//ratio w/h - not programmed yet
		this.hratio = hratio;
		this.vratio = vratio;
	}


	//you need to cast the layout to PercentageLayout to use this.  i.e.,
	//PercentageLayout pl = (PercentageLayout)getLayout();
	//pl.setDebugging(true);
	public void setDebugging(Boolean B)/>/>
	{
		debugging = b;
	}


	//note from original programmer: is bypassed - add content to content pane.
	//So, use myComponent.add(Component, String)
	//public void addLayoutComponent(Component c)
	//{
	//}


	//Main access point to add components to layout
	//Is required by layoutManager interface
	//Example 1: add(btnPanel, "7");//correct
	//Note: The component will reverse the order and call... see next line
	//getLayout().addLayoutComponent(String, Component);
	public void addLayoutComponent(String s, Component c)
	{
		//if (debugging) System.out.println("addLayoutComponent(String, Component)");
		if (debugging) System.out.println("addLayoutComponent(String=" + s + ", Component=" + c + ")");//note order is reversed from app call
		if (s.isEmpty())//i.e. add(c, s = new String());
		{
			for (int n = 0;n < rowCount * colCount;n++)
			{
				if (myComps[n] == null)
				{
					if (debugging) System.out.println("adding name=" + c.getName() + " next at " + n);
					myComps[n] = c;//set it to the component
					break;
				}
			}
		}
		else
		{
			if (debugging) System.out.println("adding [{name=" + c.getName() + " fixed  at " + Integer.valueOf(s) + "]");
			myComps[Integer.valueOf(s)] = c;
		}
	}


	//is required by layoutManager interface
	public void removeLayoutComponent(Component c)
	{
		if (debugging) System.out.println("removeLayoutComponent(Component)");
		for (int n = 0;n < colCount * rowCount;n++)
		{
			if (myComps[n] == c)
			{
				if (debugging) System.out.println("removeing name=" + c.getName());
				myComps[n] = null;
				break;
			}
		}
	}


	//is required by layoutManager interface
	//calc agragate of min sizes
	@Override
	public Dimension minimumLayoutSize(Container parent)
	{
		int n = 0;
		Dimension minDim = new Dimension(0, 0);
		Dimension[] tempDim = new Dimension[rowCount * colCount];

		//get min values
		for (n = 0;n < colCount * rowCount;n++)
		{
			tempDim[n] = new Dimension();
			if (myComps[n] != null)
			{
				if (myComps[n].isMinimumSizeSet())
				{
					tempDim[n] = myComps[n].getMinimumSize();
				}
				else
				{
					tempDim[n] = new Dimension();
				}
			}
		}

		//total rows/cols, take greatest value
		for (int row = 0;row < rowCount;row++)
		{
			int t = 0;
			for (int col =  0;col < colCount;col++)
			{
				n = (row * colCount) + col;
				t = t + tempDim[n].width;
			}
			if (minDim.width < t)
				minDim.width = t;
		}

		for (int col = 0;col < colCount;col++)
		{
			int t = 0;
			for (int row =  0;row < rowCount;row++)
			{
				n = (row * colCount) + col;
				t = t + tempDim[n].height;

			}
			if (minDim.height < t)
				minDim.height = t;
		}


		return (minDim);
	}


	//is required by layoutManager interface
	@Override
	public Dimension preferredLayoutSize(Container parent)
	{
		Dimension dim = new Dimension(0, 0);
		//need to get preferredLayoutSize of children and
		//calc normal size with insets etc.

		Insets insets = parent.getInsets();
		Dimension p = parent.getSize();
		left = insets.left;
		top = insets.top;
		right = insets.right;
		bottom = insets.bottom;

		dim.width  = p.width  - (insets.left + insets.right);
		dim.height = p.height - (insets.top  + insets.bottom);

		return dim;
	}


	@Override
	//is required by layoutManager interface
	public void layoutContainer(Container parent)
	{
		if (debugging) System.out.println("layoutContainer([name=" + parent.getName() + "])");
		Component[] comps = parent.getComponents();
		int nComps = parent.getComponentCount();

		//int maxWidth = parent.getSize().width - leftBorder - rightBorder;
		//int maxHeight = parent.getSize().height - topBorder - bottomBorder;
		Point l = parent.getLocation();
		int x = (int)l.getX();
		int y = (int)l.getY();
		int totalWidth = parent.getSize().width;
		int totalHeight = parent.getSize().height;

		Insets ins = parent.getInsets();
		int top = ins.top;
		int left = ins.left;
		int bottom = ins.bottom;
		int right = ins.right;
		int w2, h2;

		if (debugging) System.out.println("parent: [name=" + parent.getName() + " x=" + parent.getX() + " y=" + parent.getY() + " w=" + parent.getWidth() + " h=" + parent.getHeight() + "]");
		//divide up the regions
		setMaxDims(parent);

		if (debugging) System.out.println("set bounds for [name=" + parent.getName() + "]");
		//set the panel's size
		y = top;
		for (int row = 0;row < rowCount;row++)
		{
			//System.out.println("row[" + row + "]");

			x = left;
			for (int col = 0;col < colCount;col++){
				//System.out.println("    col[" + col + "]");
				int n = (row * colCount) + col;//calc array index

				if (myComps[n] != null)
				{
					Component c = myComps[n];
					//if (c.isVisible())//this is from the origanal programmer - i might change it
					//{
						setComponentBounds(c, x, y, colDim[col], rowDim[row]);
						if (debugging) System.out.println("component[" + n + "],([" + row + "][" + col + "]),(x=" + c.getBounds().x + ",y=" + c.getBounds().y + ",x2=" + (c.getBounds().x + c.getBounds().width) + ",y2=" + (c.getBounds().y + c.getBounds().height) + ") Dim=(" + c.getBounds().width + "," + c.getBounds().height + "),name=[" + c.getName() + "]");
					//}
				}
				else
				{
					if (debugging) System.out.println("component[" + n + "],([" + row + "][" + col + "]) is null");
				}
				x = x + colDim[col] + hgap + 0 ;
			}
			y = y + rowDim[row] + vgap + 0;
		}
		if (debugging) System.out.println("");
	}



	public void setComponentBounds(Component c, int x, int y, int w, int h)
	{
		int w2 = w;
		int h2 = h;

		c.setBounds(x, y, w, h);

		if (c.isPreferredSizeSet())
		{
			if (debugging) System.out.println("Setting PreferredSize for [name=" + c.getName() + "]");
			if (w != c.getPreferredSize().width)
				w2 = c.getPreferredSize().width;
			if (h != c.getPreferredSize().height)
				h2 = c.getPreferredSize().height;
			c.setBounds(x, y, w2, h2);
		}
		if (c.isMaximumSizeSet())
		{
			if (debugging) System.out.println("Setting MaximumSize for [name=" + c.getName() + "]");
			if (w > c.getMaximumSize().width)
				w2 = c.getMaximumSize().width;
			if (h > c.getMaximumSize().height)
				h2 = c.getMaximumSize().height;
			c.setBounds(x, y, w2, h2);
		}
		if (c.isMinimumSizeSet())//what should this do?  Add down and right
		{
			if (debugging) System.out.println("Setting MinimumSize for [name=" + c.getName() + "]");
			if (w < c.getMinimumSize().width)
				w2 = c.getMinimumSize().width;
			if (h < c.getMinimumSize().height)
				h2 = c.getMinimumSize().height;
			c.setBounds(x, y, w2, h2);
		}
	}


	//convert rowPercent -> rowDims, colPercent -> colDim
	//find total usable space and divide it up
	public void setMaxDims(Container parent)
	{
		Insets insets = parent.getInsets();
		left = insets.left;
		top = insets.top;
		right = insets.right;
		bottom = insets.bottom;

		Dimension maxSize = parent.getSize();
		int width = maxSize.width - left - right - ((colCount - 1) * hgap);
		int height = maxSize.height - top - bottom - ((rowCount - 1) * vgap);

		for (int row = 0;row < rowCount; row++)
		{
			rowDim[row] = (int) (rowPercent[row] * height);		//divide up segments
			if (debugging) System.out.println("rowDim[" + row + "]=" + rowDim[row]);
		}

		for (int col = 0;col < colCount; col++)
		{
			colDim[col] = (int) (colPercent[col] * width);		//divide up segments
			if (debugging) System.out.println("colDim[" + col + "]=" + colDim[col]);
		}
		if (debugging) System.out.println();
	}


	public String toString()
	{
		StringBuffer rDims = new StringBuffer(), cDims = new StringBuffer();

		for (int row = 0;row < rowCount; row++)
		{
			rDims.append(rowDim[row]);
			if (row < rowCount - 1) rDims.append(",");
		}

		for (int col = 0;col < colCount; col++)
		{
			cDims.append(colDim[col]);
			if (col < colCount - 1) cDims.append(",");
		}

		String s = new String("PercentageLayout[rows=" + rowCount + ",columns=" + colCount + ", row heights=" + rDims + " column widths=" + cDims + "]");
		return s;
	}


}

This post has been edited by Atli: 23 June 2013 - 06:35 PM
Reason for edit:: Use [code] tags when posting code.


Is This A Good Question/Topic? 0
  • +

Replies To: Virtual Solar System in Jave3D and Swing

#2 macosxnerd101  Icon User is online

  • Self-Trained Economist
  • member icon




Reputation: 10397
  • View blog
  • Posts: 38,473
  • Joined: 27-December 08

Re: Virtual Solar System in Jave3D and Swing

Posted 23 June 2013 - 06:39 PM

Quote

Things should orbit Ė the earth around the sun, the moon around the earth and a ship around the Earth Ė on their own.

Have you looked into Kepler's laws?

Quote

Iíd like to add rotational velocity to the ship on earth so that it moves to the same spot on the rotating earth.

There are a ton of tutorials on rotational kinematics.

Quote

Any help will be appreciated. I need someone who is good in trig and calc to take vectors and the speed and calculate the movement of the planets and ships.

What have you tried? The Java Game Programming Thread has some relevant tutorials, and I have a series of Calculus primers.

I've never worked with the Java3D API before, so I may not be the best person to troubleshoot Java3D specific code. I'm happy to help with specifics, especially on the math end. If you can narrow your problem down on that end and get me some more specifics, I can probably get you a better answer.
Was This Post Helpful? 0
  • +
  • -

#3 PGR  Icon User is offline

  • D.I.C Head

Reputation: 13
  • View blog
  • Posts: 55
  • Joined: 10-January 11

Re: Virtual Solar System in Jave3D and Swing

Posted 23 June 2013 - 06:50 PM

You can get Jave3D here.
https://java3d.java....ary-builds.html
Was This Post Helpful? 0
  • +
  • -

#4 macosxnerd101  Icon User is online

  • Self-Trained Economist
  • member icon




Reputation: 10397
  • View blog
  • Posts: 38,473
  • Joined: 27-December 08

Re: Virtual Solar System in Jave3D and Swing

Posted 23 June 2013 - 06:57 PM

I know that. I've just never installed it or played around with it, and I don't really intend to do so. Java3D is a dead technology really, and there are more commonly used 3D graphics APIs for Java that I'd probably look at if I were so inclined.
Was This Post Helpful? 0
  • +
  • -

#5 PGR  Icon User is offline

  • D.I.C Head

Reputation: 13
  • View blog
  • Posts: 55
  • Joined: 10-January 11

Re: Virtual Solar System in Jave3D and Swing

Posted 23 June 2013 - 07:18 PM

My two math problems are
given x, y, z and xv, yv, zv and xr, yr, zr and Gravity is F = G((m1*m2)/r^2) - does it change from metric to standard?
1) finding the angle between two/three axis (for a ship in orbit) so I can change the velocity by adding the effects of gravity to a floating body. i.e.,
I want to increase xv, yv, zv by gravity so
xv = xv + F * (and I get stuck) I understand sin/cos but just barely passed algebra in college and don't know what to use. Oh, I found atan2() the other day. I think I need that here.

2) The other problem is similar. with x, y, z and xr, yr, zr, if I give my ship thrust, how do I break up the thrust to change xv, yv, zv. I want to break it up, then add the parts to the velocities and the multiply by the thrust (and divide by the frames per second to interpolate it over a second).
Was This Post Helpful? 0
  • +
  • -

#6 PGR  Icon User is offline

  • D.I.C Head

Reputation: 13
  • View blog
  • Posts: 55
  • Joined: 10-January 11

Re: Virtual Solar System in Jave3D and Swing

Posted 23 June 2013 - 08:20 PM

In VRML there is a command (ccw) to draw the inside face of the shape. I want to add atmosphere to earth and putting a sphere around it the depth of the atmosphere with the color in the inside is a good way of doing it. that way, from space, you look through the atmosphere and see the other side and it doesn't hide the Earth. Has anyone seen this in Java3D?
Also, there is a command to soften the ridges of a shape to make a sphere look round instead of being made up of a bunch of triangles. Has anyone seen this?
Was This Post Helpful? 0
  • +
  • -

#7 macosxnerd101  Icon User is online

  • Self-Trained Economist
  • member icon




Reputation: 10397
  • View blog
  • Posts: 38,473
  • Joined: 27-December 08

Re: Virtual Solar System in Jave3D and Swing

Posted 23 June 2013 - 08:58 PM

Quote

does it change from metric to standard?

The equation doesn't change. Some of the constants like G have different numeric values that represent the same thing. It's up to you to do the appropriate unit conversions.

Quote

I understand sin/cos but just barely passed algebra in college

The math requirements for this project are going to be intense. You need to invest time in self-studying or taking classes. You'll really want some good classes in Calc I-III, Differential Equations, and Linear Algebra, if you decide to go back and take these classes. It's pretty much 1-3 classes short of a math minor, depending on the college in question.

Quote

F = G((m1*m2)/r^2)

Remember that F = (m1)a = G((m1*m2)/r^2). So it's easy to solve for a. So xv_{i+1} = xv_{i} + a_{v} * t. Here, r is the distance (vector magnitude). You essentially extend the Pythagorean theorem here. Now we have: a = G(m2)/(x2 + y2 + z2). You could probably use Euler's method for approximating differential equations as a numerical solution here. So take the current (x, y, z) point and use it to solve for a(t). Then for each coordinate, you'll want to take the acceleration for that component. You might find Spherical Coordinates useful here.
Was This Post Helpful? 1
  • +
  • -

#8 PGR  Icon User is offline

  • D.I.C Head

Reputation: 13
  • View blog
  • Posts: 55
  • Joined: 10-January 11

Re: Virtual Solar System in Jave3D and Swing

Posted 25 June 2013 - 04:58 PM

I'm still looking at those formulas.
Does anyone know how to add multiple views to a scene? I want to see a ship and have a ship view and look at some other things at the same time.

(I'm looking for a good book but, most books stop right where I want to start. Ship thrust in 3d is one example of that. )
Was This Post Helpful? 0
  • +
  • -

#9 PGR  Icon User is offline

  • D.I.C Head

Reputation: 13
  • View blog
  • Posts: 55
  • Joined: 10-January 11

Re: Virtual Solar System in Jave3D and Swing

Posted 26 June 2013 - 12:47 AM

View Postmacosxnerd101, on 23 June 2013 - 06:57 PM, said:

I know that. I've just never installed it or played around with it, and I don't really intend to do so. Java3D is a dead technology really, and there are more commonly used 3D graphics APIs for Java that I'd probably look at if I were so inclined.

What's you favorite Java 3D API. I'm not tied to anything.
Was This Post Helpful? 0
  • +
  • -

#10 macosxnerd101  Icon User is online

  • Self-Trained Economist
  • member icon




Reputation: 10397
  • View blog
  • Posts: 38,473
  • Joined: 27-December 08

Re: Virtual Solar System in Jave3D and Swing

Posted 26 June 2013 - 07:32 AM

I've heard good things about Java OpenGL. I do zero 3D Graphics work, so I'm probably not the best person to talk about the innards of the API. :)
Was This Post Helpful? 0
  • +
  • -

#11 jon.kiparsky  Icon User is offline

  • Pancakes!
  • member icon


Reputation: 7578
  • View blog
  • Posts: 12,743
  • Joined: 19-March 11

Re: Virtual Solar System in Jave3D and Swing

Posted 26 June 2013 - 07:45 AM

It seems to me that thinking too much about the 3D rendering library might be jumping the gun if you're still working on the math of it. Ideally, you'd like to have a modeling engine that spits out positions, and then be able to try out different 3D graphics libraries against that.

That would also tend to enforce a solid architecture, which will be nice to have.
Was This Post Helpful? 1
  • +
  • -

#12 PGR  Icon User is offline

  • D.I.C Head

Reputation: 13
  • View blog
  • Posts: 55
  • Joined: 10-January 11

Re: Virtual Solar System in Jave3D and Swing

Posted 26 June 2013 - 01:14 PM

This is an example of the cart before the horse problem. Both the math and the virtual environment are needed. Having something that others can look at and play with, keeps them coming back for more and might inspire them to help. All the stuff the I found on the internet says ďJava3DĒ and ďSwingĒ but, they just throw up a JFrame and add a few lines of code to throw something up on the screen. This is organized properly with...
    SwingUtilities.invokeAndWait(new Runnable(){
        public void run(){
             initGUI();
       }



I forgot that I have an old attempt at this and I did have a ship flying around the Sun, the Earth and the Moon. Iíve flown at light speed. Eight minutes to the sun. Then my sin and cos started to go off. I have discovered that I had my Ys and Zs wrong. For anyone who is new to this, there is the right hand rule or the left hand rule. Hold your hand up and look at the palm of your hand. Curl in the bottom two fingers and then the next one a little more. Your index finger represents the x axis and points to the increasing x direction. Your middle finger represents the z axis and points to higher z values. Your thumb represents the y axis and points to higher y values. All your libraries (Vector3d, i.e.) have to use the same system. I abandoned that library because it didnít support multi-views.

I can throw planets up easily. Getting the transform and moving cameras around is only a matter of accessing the transform and changing the values which is hard because I canít find a good book on it. I do this...

//          name,          mass,        radius,     x,    y,   z,  xv,  yv,  zv,  xr,  yr,  zr, xrv, yrv, zrv, 
Object[][] myMass = {    
    {"Sun",     "1.99e+9", "5.59648e+11",               "0", "0",         "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0"},//,
    {"Earth", "5973.6e21", "1.49669e+11",      "6371000, 0", "0",         "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0"},
    {"Moon",   "7.371e22",   "173711000",     "1.49669E+11", "0", "384403000", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0"},
};




The make the VWorld

public void initGUI(){

GraphicsConfiguration config = SimpleUniverse.getPreferredConfiguration();
window0 = new Canvas3D(config);
window0.setMinimumSize(new Dimension(10, 10));
window0.setVisible(true);
getContentPane().add(window0, "0");

uni = new SimpleUniverse(window0);
uni.getViewingPlatform().setNominalViewingTransform();
uni.getViewer().getView().setMinimumFrameCycleTime(5);

group = new BranchGroup();
//uni.addBranchGraph(group);//but must be done at end of init

//add stuff
for (int i = 0; i < myMass.length;i++){
    group.addChild(getMass(i));
}

//add group to the universe
uni.addBranchGraph(group);
}



then make the planets and ships

    public Mass3D getMass(int i){
            System.out.println("Make mass (" + i + ")");

            //name/type, mass, diameter, location, velocity, rotation, rotation vector, scale, length
            //TransformGroup tGroup = new TransformGroup();//temporary setting
            Mass3D tGroup = new Mass3D();
            Transform3D tTrans;
            double[]    v = new double[16];
            Vector3D    trot;
            Appearance tApp;
            ColoringAttributes ca;
            RotationInterpolator rotator;
            BoundingSphere bounds;
            String col;
            Alpha rotationAlpha;
            Shape3D tShape;
            Sphere tSphere;
            Geometry    tGeo;
            //node = new Node();
            switch (i){
                    case 0://sun
                            tGroup = new Mass3D();
                            tGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
                            tGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
                            //decode the mass array string data
                            tGroup.setName((String)myMass[i][0]);
                            tGroup.setMass(Double.valueOf((String)myMass[i][1]));
                            tGroup.setRadius(Double.valueOf((String)myMass[i][2]));
                            v[ 0] = Double.valueOf((String)myMass[i][ 3]);//x
                            //etc

                            //set up location and rotation
                            //tTrans = new Transform3D(v);
                            tTrans = new Transform3D();
                            tTrans.set(new Vector3d(0, 0d, -v[3]));//move it back from camera
                            tGroup.setTransform(tTrans);

                            //rotationAlpha = new Alpha(-1, 40);
                            //rotator = new RotationInterpolator(rotationAlpha, tGroup, tTrans, 0.0f, (float)Math.PI*2.0f);
                            //bounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 100.0);
                            //rotator.setSchedulingBounds(bounds);
                            float r = Float.valueOf((String)myMass[i][2]);
                            ca = new ColoringAttributes();
                            ca.setColor(new Color3f(1, 1, 0));
                            tApp = new Appearance();
                            tApp.setColoringAttributes(ca);
                            //PolygonAttributes.setBackFaceNormalFlip();
                            //tApp.setRenderingAttributes(RenderingAttributes.);
                            tGroup.addChild(new Sphere(r, tApp));
                    break;

                    default:
                            System.out.println("getMass object " + i + " not found.  Ooops!");
                            break;
            }
            return(tGroup);
    }


Was This Post Helpful? 0
  • +
  • -

#13 macosxnerd101  Icon User is online

  • Self-Trained Economist
  • member icon




Reputation: 10397
  • View blog
  • Posts: 38,473
  • Joined: 27-December 08

Re: Virtual Solar System in Jave3D and Swing

Posted 26 June 2013 - 01:31 PM

Quote

I can throw planets up easily. Getting the transform and moving cameras around is only a matter of accessing the transform and changing the values which is hard because I canít find a good book on it. I do this...

This is all Linear Algebra. You might be better served by investing in a good Linear Algebra textbook.
Was This Post Helpful? 0
  • +
  • -

#14 PGR  Icon User is offline

  • D.I.C Head

Reputation: 13
  • View blog
  • Posts: 55
  • Joined: 10-January 11

Re: Virtual Solar System in Jave3D and Swing

Posted 01 July 2013 - 09:32 PM

I can fly around a bit but, everything is still in the sun. I’ll move things away now that I can actually fly around things and look at them. I can add multiple cameras and monitors. I put the monitors in an array so, you can get to them when you do initGUI()
You have to set the thrust to set the focus so, the key commands work. i, j, k, m.
Below is how to add many cameras/monitors.
ArrayList            camera = new ArrayList();//movable cameras
ArrayList            monitor = new ArrayList();//camera monitors

init(){
GraphicsConfiguration config = SimpleUniverse.getPreferredConfiguration();
mainWindow = new Canvas3D(config);
uni = new SimpleUniverse(mainWindow);
uni.getViewingPlatform().setNominalViewingTransform();
uni.getViewer().getView().setBackClipDistance(1.2e13);
uni.getViewer().getView().setMinimumFrameCycleTime(5);
group = new BranchGroup();

group.addChild(getSomething());//add a camera to it

initGUI()
monitorPanel = new JPanel(new PercentageLayout(2, 2, new int[]{50, 50}, new int[]{50, 50}));//h, w
for (int i = 0; i < monitor.size(); i++){
    monitorPanel.add((Canvas3D) monitor.get(i), Integer.toString(i));
}
}


public TransformGroup getSomething()
TransformGroup tGroup = new Controlable();

//set up location and rotation
tTrans = new Transform3D();
tTrans.set(new Vector3d(x, y, z));//x, y, z

//adjust rotation to point the correct way
trot = new Vector3d(Math.toRadians(xr), yr, zr);//computers work in radians
tTrans.setEuler(trot);//input (xr, yr, zr), output angle and amount of rotation
tGroup.setTransform(tTrans);

//set up color, etc
tApp = new Appearance();
ca = new ColoringAttributes();
ca.setColor(new Color3f(1, 1f, 1f));
tApp.setColoringAttributes(ca);
tGroup.addChild(new Cone(tRadius, 2f, tApp));//add ship

//set up camera transform
tGroup2 = new TransformGroup();
tTrans2 = new Transform3D();
tTrans2.setTranslation(tGroup.location = new Vector3d());//center of ship for now
tTrans2.setEuler(tGroup.rotation = new Vector3d(Math.toRadians(90), 0, 0));//input (xr, yr, zr), output angle and amount of rotation
tGroup2.setTransform(tTrans2);
tGroup2.addChild(getNewCamera());//add camera

//add camera transform to ship
tGroup.addChild(tGroup2);

return(tGroup);
//return object




public ViewPlatform getNewCamera(){
    ViewPlatform tVP = new ViewPlatform();//the camera
    Canvas3D     tCam;
    
    View tView = new View();//camera/monitor link
    tView.setPhysicalBody(new PhysicalBody());
    tView.setPhysicalEnvironment(new PhysicalEnvironment());
    tView.setBackClipDistance(SYSTEMDIAMETER);
    tView.addCanvas3D(tCam = new Canvas3D(SimpleUniverse.getPreferredConfiguration()));
    tView.attachViewPlatform(tVP);//connect camera and monitor
    monitor.add(tCam);//add them to a panel when GUI is created
    
    return(tVP);
}

Attached File(s)


This post has been edited by macosxnerd101: 03 July 2013 - 09:02 PM
Reason for edit:: Please use code tags

Was This Post Helpful? 0
  • +
  • -

#15 macosxnerd101  Icon User is online

  • Self-Trained Economist
  • member icon




Reputation: 10397
  • View blog
  • Posts: 38,473
  • Joined: 27-December 08

Re: Virtual Solar System in Jave3D and Swing

Posted 03 July 2013 - 09:03 PM

Just an FYI- ArrayLists are generic. You should really be using generics with them, if for no other reason than to avoid the nasty deprecation warnings.
Was This Post Helpful? 0
  • +
  • -

  • (2 Pages)
  • +
  • 1
  • 2