import java.applet.Applet; import java.awt.*; import java.awt.event.*; import java.awt.Font; import com.sun.j3d.utils.applet.MainFrame; import com.sun.j3d.utils.universe.*; import com.sun.j3d.utils.image.TextureLoader; import com.sun.j3d.utils.behaviors.mouse.*; import com.sun.j3d.utils.image.*; import com.sun.j3d.utils.applet.*; import com.sun.j3d.utils.geometry.*; import com.sun.j3d.utils.*; import javax.media.j3d.*; import javax.vecmath.*; import java.awt.BorderLayout; import java.awt.Frame; import java.applet.Applet; import com.sun.j3d.utils.applet.MainFrame; import java.util.*; import java.awt.geom.*; import java.awt.image.*; import java.awt.event.*; public class GalaxyBlackHole extends Applet { double d, acc; Random rnd = new Random(); int n = 2; //rnd.nextInt(5); int gal = 500; double G = 1; int size = 1; int dxy = 100; int clipx = 1024; int clipy = 768; int p = 0, i = 0, k = 0, j = 0; Star glx[][] = new Star[n][gal]; PointArray parr; Shape3D s3d; Star s[] = new Star[n]; Sphere sphere; TransformGroup trs; public class Star{ public Star(){ pos = new double[3]; vel = new double[3]; acc = new double[3]; } public double pos[]; public double vel[]; public double acc[]; public Color3f color; public double mass; } double ep = 0.00001; double ts = 0.0; double x1, x2, x3; WakeupOnElapsedTime wup = new WakeupOnElapsedTime(5000); int flag = 0; public class Moving extends Interpolator { public Moving(Alpha alpha){ super(alpha); } Vector3d curr; Transform3D tmp; PointArray geom; public void processStimulus(Enumeration e) { geom = (PointArray)s3d.getGeometry(); for(int j = 0; j < 1; j++) { for(int i = 0; i < gal; i++) { for(int k = 0; k < n; k++) { x1 = glx[j][i].pos[0] - s[k].pos[0]; x2 = glx[j][i].pos[1] - s[k].pos[1]; x3 = glx[j][i].pos[2] - s[k].pos[2]; d = Math.sqrt (x1*x1 + x2*x2 + x3*x3); double ep_t_mass = -ep*s[k].mass/(d*d); //if(d < 0.7) { glx[j][i].acc[0] = ep_t_mass * x1; glx[j][i].acc[1] = ep_t_mass * x2; glx[j][i].acc[2] = ep_t_mass * x3; //} glx[j][i].vel[0] += ts * glx[j][i].acc[0]; glx[j][i].vel[1] += ts * glx[j][i].acc[1]; glx[j][i].vel[2] += ts * glx[j][i].acc[2]; glx[j][i].pos[0] += ts * glx[j][i].vel[0]; glx[j][i].pos[1] += ts * glx[j][i].vel[1]; glx[j][i].pos[2] += ts * glx[j][i].vel[2]; if(k == j) { glx[j][i].color.x = (float)(0.8 - d); glx[j][i].color.y = (float)(0.8 - d); glx[j][i].color.z = (float)(0.8 - d); } geom.setCoordinates(i*n + j, glx[j][i].pos); geom.setColor(j*n + i, glx[j][i].color); } } } s3d.setGeometry(geom); ts+=0.001; wakeupOn(defaultWakeupCriterion); } } public BranchGroup createSceneGraph() { // Create the root of the branch graph BranchGroup objRoot = new BranchGroup(); objRoot.setCapability(BranchGroup.ALLOW_DETACH); objRoot.setCapability(BranchGroup.ALLOW_CHILDREN_WRITE); objRoot.setCapability(BranchGroup.ALLOW_CHILDREN_READ); Transform3D t3D = new Transform3D(); TransformGroup objRotate = new TransformGroup(); objRotate.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); objRotate.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); Transform3D trc = new Transform3D(); trc.setTranslation(new Vector3f((float)s[1].pos[0], (float)s[1].pos[1], (float)s[1].pos[2])); trs = new TransformGroup(trc); trs.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); trs.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); trs.setCapability(BranchGroup.ALLOW_CHILDREN_WRITE); trs.setCapability(BranchGroup.ALLOW_CHILDREN_READ); Appearance ap = new Appearance(); ColoringAttributes ca = new ColoringAttributes(0.8f, 0.0f, 0f, ColoringAttributes.NICEST); ap.setColoringAttributes(ca); sphere = new Sphere(0.05f, ap); trs.addChild(sphere); objRotate.addChild(trs); // cover all different angles in a box float bndry[][] = { {-2f, -2f, -2f}, {-2f, 2f, -2f}, { 2f, -2f, -2f}, { 2f, 2f, -2f}, {-2f, -2f, 2f}, {-2f, 2f, 2f}, { 2f, -2f, 2f}, { 2f, 2f, 2f}, }; // build a box to aid visualisation LineArray la = new LineArray(24, LineArray.COORDINATES | LineArray.COLOR_3); la.setCoordinates(0, bndry[0]); la.setColor(0, new Color3f(0.4f, 0.4f, 0.4f)); la.setCoordinates(1, bndry[1]); la.setColor(1, new Color3f(0.4f, 0.4f, 0.4f)); la.setCoordinates(2, bndry[2]); la.setColor(2, new Color3f(0.4f, 0.4f, 0.4f)); la.setCoordinates(3, bndry[3]); la.setColor(3, new Color3f(0.4f, 0.4f, 0.4f)); la.setCoordinates(4, bndry[4]); la.setColor(4, new Color3f(0.4f, 0.4f, 0.4f)); la.setCoordinates(5, bndry[5]); la.setColor(5, new Color3f(0.4f, 0.4f, 0.4f)); la.setCoordinates(6, bndry[6]); la.setColor(6, new Color3f(0.4f, 0.4f, 0.4f)); la.setCoordinates(7, bndry[7]); la.setColor(7, new Color3f(0.4f, 0.4f, 0.4f)); la.setCoordinates(8, bndry[0]); la.setColor(8, new Color3f(0.4f, 0.4f, 0.4f)); la.setCoordinates(9, bndry[4]); la.setColor(9, new Color3f(0.4f, 0.4f, 0.4f)); la.setCoordinates(10, bndry[1]); la.setColor(10, new Color3f(0.4f, 0.4f, 0.4f)); la.setCoordinates(11, bndry[5]); la.setColor(11, new Color3f(0.4f, 0.4f, 0.4f)); la.setCoordinates(12, bndry[2]); la.setColor(12, new Color3f(0.4f, 0.4f, 0.4f)); la.setCoordinates(13, bndry[6]); la.setColor(13, new Color3f(0.4f, 0.4f, 0.4f)); la.setCoordinates(14, bndry[3]); la.setColor(14, new Color3f(0.4f, 0.4f, 0.4f)); la.setCoordinates(15, bndry[7]); la.setColor(15, new Color3f(0.4f, 0.4f, 0.4f)); la.setCoordinates(16, bndry[0]); la.setColor(16, new Color3f(0.4f, 0.4f, 0.4f)); la.setCoordinates(17, bndry[2]); la.setColor(17, new Color3f(0.4f, 0.4f, 0.4f)); la.setCoordinates(18, bndry[1]); la.setColor(18, new Color3f(0.4f, 0.4f, 0.4f)); la.setCoordinates(19, bndry[3]); la.setColor(19, new Color3f(0.4f, 0.4f, 0.4f)); la.setCoordinates(20, bndry[4]); la.setColor(20, new Color3f(0.4f, 0.4f, 0.4f)); la.setCoordinates(21, bndry[6]); la.setColor(21, new Color3f(0.4f, 0.4f, 0.4f)); la.setCoordinates(22, bndry[5]); la.setColor(22, new Color3f(0.4f, 0.4f, 0.4f)); la.setCoordinates(23, bndry[7]); la.setColor(23, new Color3f(0.4f, 0.4f, 0.4f)); Shape3D b = new Shape3D(la, new Appearance()); objRotate.addChild(b); parr = new PointArray(n*gal, PointArray.COORDINATES | PointArray.COLOR_3); parr.setCapability(PointArray.ALLOW_COORDINATE_READ); parr.setCapability(PointArray.ALLOW_COORDINATE_WRITE); parr.setCapability(PointArray.ALLOW_COLOR_READ); parr.setCapability(PointArray.ALLOW_COLOR_WRITE); for(int j = 0; j < 1; j++) { for(i = 0; i < gal; i++) { parr.setCoordinates(i*n + j, glx[j][i].pos); parr.setColor(i*n + j, glx[j][i].color); //parr.setColor(i*n + j, new Color3f(1, 1, 1)); } } s3d = new Shape3D(parr, new Appearance()); s3d.setCapability(Shape3D.ALLOW_GEOMETRY_READ); s3d.setCapability(Shape3D.ALLOW_GEOMETRY_WRITE); objRotate.addChild(s3d); Alpha alpha = new Alpha(-1, 1000); Moving mov = new Moving(alpha); mov.setSchedulingBounds(new BoundingSphere()); objRotate.addChild(mov); MouseRotate myMouseRotate = new MouseRotate(); myMouseRotate.setTransformGroup(objRotate); myMouseRotate.setSchedulingBounds(new BoundingSphere()); objRoot.addChild(myMouseRotate); MouseTranslate myMouseTranslate = new MouseTranslate(); myMouseTranslate.setTransformGroup(objRotate); myMouseTranslate.setSchedulingBounds(new BoundingSphere()); objRoot.addChild(myMouseTranslate); MouseZoom myMouseZoom = new MouseZoom(); myMouseZoom.setTransformGroup(objRotate); myMouseZoom.setSchedulingBounds(new BoundingSphere()); objRoot.addChild(myMouseZoom); objRoot.addChild(objRotate); objRoot.compile(); return objRoot; } // end of CreateSceneGraph method public GalaxyBlackHole() { } // The following allows this to be run as an application // as well as an applet public static void main(String[] args) { Frame frame = new MainFrame(new GalaxyBlackHole(), 512, 512); } // end of main (method of TexturedText3DApp) public void init() { for(int i = 0; i < n; i++) { s[i] = new Star(); switch(i) { case 0: s[i].pos[0] = 0f; s[i].pos[1] = 0f; s[i].pos[2] = 0f; s[i].vel[0] = 0f; // s[i].vel[1] = -0.005f; //s[i].vel[2] = 0f; s[i].mass = 500; break; case 1: s[i].pos[0] = -1f; s[i].pos[1] = -1f; s[i].pos[2] = -1f; //s[i].vel[0] = 0.05f; s[i].vel[1] = 0.05f; //s[i].vel[2] = 0f; s[i].mass = 1000; break; } } glx = new Star[n][gal]; for(int j = 0; j < 1; j++) { for(i = 0; i < gal; i++) { glx[j][i] = new Star(); glx[j][i].pos[0] = s[j].pos[0] + (rnd.nextBoolean() ? rnd.nextDouble() : -rnd.nextDouble()); glx[j][i].pos[1] = s[j].pos[1] + (rnd.nextBoolean() ? rnd.nextDouble() : -rnd.nextDouble()); glx[j][i].pos[2] = s[j].pos[2] + (rnd.nextBoolean() ? rnd.nextDouble()/5 : -rnd.nextDouble()/5); double dist = Math.sqrt( Math.pow(glx[j][i].pos[0] - s[j].pos[0], 2) + Math.pow(glx[j][i].pos[1] - s[j].pos[1], 2) + Math.pow(glx[j][i].pos[2] - s[j].pos[2], 2)); if(dist > 0.5) { i--; continue; } else { glx[j][i].pos[2] = s[j].pos[2] + (glx[j][i].pos[2]-s[j].pos[2]) / (10 *dist) ; } double dx = glx[j][i].pos[0] - s[j].pos[0]; double dy = glx[j][i].pos[1] - s[j].pos[1]; glx[j][i].vel[0] = -dy*0.157 + s[j].vel[0]; glx[j][i].vel[1] = dx*0.157 + s[j].vel[1]; glx[j][i].vel[2] = s[j].vel[2]; glx[j][i].color = new Color3f((float)(0.9 - dist), (float)(0.9 - dist), (float)(0.9 - dist)); //glx[j][i].color = new Color3f(1f, 1f, 1f); glx[j][i].acc[0] = glx[j][i].acc[1] = 0; glx[j][i].mass = 1; } } setLayout(new BorderLayout()); GraphicsConfiguration config = SimpleUniverse.getPreferredConfiguration(); Canvas3D c = new Canvas3D(config); add("Center", c); // Create a simple scene and attach it to the virtual universe BranchGroup scene = createSceneGraph(); SimpleUniverse u = new SimpleUniverse(c); // This will move the ViewPlatform back a bit so the // objects in the scene can be viewed. u.getViewingPlatform().setNominalViewingTransform(); u.addBranchGraph(scene); } }