Browse Source

incomplete HolonCanvas with bad collision detection

jess 7 years ago
parent
commit
9c31abb2fa

+ 61 - 0
src/classes/HolonBody.java

@@ -0,0 +1,61 @@
+package classes;
+import java.awt.Color;
+
+public class HolonBody {
+  private static final double G = 6.673e-11;   // gravitational constant
+  
+  public int rx, ry;       // holds the cartesian positions
+  public double vx, vy;       // velocity components 
+  public double fx, fy;       // force components
+  public double mass;         // mass
+  public Color color;         // color 
+  
+  // create and initialize a new Body
+  public HolonBody(int rx, int ry, double vx, double vy, double mass, Color color) {
+    this.rx    = rx;
+    this.ry    = ry;
+    this.vx    = vx;
+    this.vy    = vy;
+    this.mass  = mass;
+    this.color = color;
+  }
+  
+  // update the velocity and position using a timestep dt
+  public void update(double dt) {
+    vx += dt * fx / mass;
+    vy += dt * fy / mass;
+    rx += dt * vx;
+    ry += dt * vy;
+  }
+  
+  // returns the distance between two bodies
+  public double distanceTo(HolonBody b) {
+    double dx = rx - b.rx;
+    double dy = ry - b.ry;
+    return Math.sqrt(dx*dx + dy*dy);
+  }
+  
+  // set the force to 0 for the next iteration
+  public void resetForce() {
+    fx = 0.0;
+    fy = 0.0;
+  }
+  
+  // compute the net force acting between the body a and b, and
+  // add to the net force acting on a
+  public void addForce(HolonBody b) {
+    HolonBody a = this;
+    double EPS = 3E4;      // softening parameter (just to avoid infinities)
+    double dx = b.rx - a.rx;
+    double dy = b.ry - a.ry;
+    double dist = Math.sqrt(dx*dx + dy*dy);
+    double F = (G * a.mass * b.mass) / (dist*dist + EPS*EPS);
+    a.fx += F * dx / dist;
+    a.fy += F * dy / dist;
+  }
+  
+  // convert to string representation formatted nicely
+  public String toString() {
+    return "" + rx + ", "+ ry+ ", "+  vx+ ", "+ vy+ ", "+ mass;
+  }
+}

+ 15 - 1
src/classes/SubNet.java

@@ -12,7 +12,7 @@ public class SubNet {
 	private ArrayList<HolonObject> subNetObjects;
 	private ArrayList<CpsEdge> subNetEdges;
 	private ArrayList<HolonSwitch> subNetSwitches;
-
+	private Position pos;
 	/**
 	 * Constructor for a Subnet.
 	 * 
@@ -54,4 +54,18 @@ public class SubNet {
 	public ArrayList<HolonSwitch> getSwitches() {
 		return subNetSwitches;
 	}
+
+
+	public Position getPos() {
+		return pos;
+	}
+
+	public void setPos(Position pos) {
+		this.pos = pos;
+	}
+	
+	public void setPos(int x, int y){
+		this.pos.x = x;
+		this.pos.y = y;
+	}
 }

+ 0 - 1
src/ui/controller/NodeController.java

@@ -8,7 +8,6 @@ import classes.AbstractCpsObject;
 import classes.CpsEdge;
 import classes.CpsUpperNode;
 import classes.Position;
-import javafx.collections.ListChangeListener;
 import ui.model.Model;
 import ui.view.UpperNodeCanvas;
 

+ 4 - 4
src/ui/view/GUI.java

@@ -118,7 +118,7 @@ public class GUI<E> implements CategoryListener {
 
 	private final JScrollPane canvasSP = new JScrollPane();
 	private final JScrollPane scrollPane1 = new JScrollPane();
-	private final JScrollPane holonSP = new JScrollPane();
+	//private final JScrollPane holonSP = new JScrollPane();
 	private final JTabbedPane tabbedPane = new JTabbedPane(JTabbedPane.TOP);
 	private final JPanel panelTapped_SimMenu = new JPanel();
 	private JPopupMenu popmenuEdit = new JPopupMenu();
@@ -1579,7 +1579,7 @@ public class GUI<E> implements CategoryListener {
 		splitPaneCanvasConsole.setLeftComponent(panelTapped_SimMenu);
 		tabbedPane.addTab("View", canvasSP);
 		tabbedPane.addTab("Statistics", statScrollPane);
-		tabbedPane.addTab("Holon", holonSP);
+		tabbedPane.addTab("Holon", holonCanvas);
 
 		splitPaneCanvasConsole.setRightComponent(console);
 		splitPane1.setLeftComponent(splitPaneCanvasConsole);
@@ -1594,7 +1594,7 @@ public class GUI<E> implements CategoryListener {
 		splitGraphHolonEl.setTopComponent(scrollGraph);
 		splitGraphHolonEl.setBottomComponent(scrollElements);
 		canvasSP.setViewportView(canvas);
-		holonSP.setViewportView(holonCanvas);
+		//holonSP.setViewportView(holonCanvas);
 		panelTapped_SimMenu.setLayout(new BorderLayout());
 		panelTapped_SimMenu.add(simMenu, BorderLayout.NORTH);
 		panelTapped_SimMenu.add(tabbedPane);
@@ -1612,7 +1612,7 @@ public class GUI<E> implements CategoryListener {
 		splitGraphHolonEl.setBorder(null);
 		panelHolonEl.setBorder(null);
 		canvasSP.setBorder(null);
-		holonSP.setBorder(null);
+		//holonSP.setBorder(null);
 
 		tableHolonElementScrollPane.setBorder(null);
 

+ 104 - 19
src/ui/view/HolonCanvas.java

@@ -4,15 +4,17 @@
 package ui.view;
 
 import java.awt.Color;
+import java.awt.Dimension;
 import java.awt.Graphics;
 import java.awt.Graphics2D;
-import java.awt.Image;
-import java.awt.RenderingHints;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.ArrayList;
 
-import javax.swing.ImageIcon;
 import javax.swing.JPanel;
+import javax.swing.Timer;
 
-import classes.HolonObject;
+import classes.HolonBody;
 import classes.SubNet;
 import ui.controller.Control;
 import ui.model.Model;
@@ -23,12 +25,18 @@ import ui.model.Model;
  * @author Gruppe14
  *
  */
-public class HolonCanvas extends JPanel {
+public class HolonCanvas extends JPanel implements ActionListener {
 	private static final long serialVersionUID = 1L;
 	// edge Object Start Point
 	private Model model;
 	private final Control controller;
 	Graphics2D g2; // For Painting
+	private int N;
+	private ArrayList<HolonBody> bodies;
+	private Timer timer = new Timer(33, this);
+	private Dimension center;
+	private ArrayList<SubNet> subnets;
+	private int rx, ry;
 
 	/**
 	 * Constructor.
@@ -41,25 +49,102 @@ public class HolonCanvas extends JPanel {
 	public HolonCanvas(Model mod, Control control) {
 		this.controller = control;
 		this.model = mod;
+		subnets = controller.getSimManager().getSubNets();
+		N = subnets.size();
+		bodies = new ArrayList<>();
+		calcCenter();
+		timer.start();
 	}
 
 	public void paintComponent(Graphics g) {
 		super.paintComponent(g);
-		// Rendering
-		g2 = (Graphics2D) g;
-		RenderingHints rh = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
-		g2.setRenderingHints(rh);
+		if (!controller.getSimManager().getSubNets().equals(subnets)) {
+			subnets = controller.getSimManager().getSubNets();
+			N = subnets.size();
+			N += 1;
+			bodies = new ArrayList<>();
+			startthebodies(N);
+		}
+		for (int i = 0; i < N; i++) {
+			g.setColor(bodies.get(i).color);
+			if (i != 0) {
+				g.fillOval(bodies.get(i).rx, bodies.get(i).ry, subnets.get(i - 1).getObjects().size() * 8,
+						subnets.get(i - 1).getObjects().size() * 8);
+			} else
+				g.fillOval(bodies.get(0).rx, bodies.get(0).ry, 0, 0);
+		}
+		addforces(N);
+	}
+
+	// Initialize N bodies with random positions
+	public void startthebodies(int N) {
+		double solarmass = 1.98892e30;
+		calcCenter();
+		// the central mass
+		bodies.add(0, new HolonBody(center.width, center.height, 0, 0, 1e6 * solarmass, new Color(0, 0, 0)));
+		for (int i = 0; i < N - 1; i++) {
+			int px = (int) (Math.random() * 201);
+			int py = (int) (Math.random() * 201);
+
+			double mass = (subnets.get(i).getObjects().size()) / 10 * solarmass * 10 + 1e20;
+			Color color = model.getSubNetColors().get(i);
+			bodies.add(new HolonBody(px, py, 0, 0, mass, color));
+		}
+	}
+
+	// reset the forces, then add all the new forces
+	public void addforces(int N) {
+		for (int i = 0; i < N; i++) {
+			bodies.get(i).resetForce();
+
+			for (int j = 0; j < N; j++) {
+				if (i != j)
+					bodies.get(i).addForce(bodies.get(j));
+			}
+		}
+		// loop again and update the bodies using timestep dt
+		for (int i = 1; i < N; i++) {
+			rx = bodies.get(i).rx;
+			ry = bodies.get(i).ry;
+			bodies.get(i).update(1e-9);
+			if (checkCollison(i)) {
+				bodies.get(i).rx = rx;
+				bodies.get(i).ry = ry;
+				bodies.get(i).vx = 0;
+				bodies.get(i).vy = 0;
+			}
+		}
+	}
 
-		int i = 0;
-		int k = 0;
-		// Objects
-		for (SubNet s : controller.getSimManager().getSubNets()) {
-			// draw image
-			g2.setColor(model.getSubNetColors().get(k));
-			g2.fillOval(10 + i, 10 + i, controller.getScale() * s.getObjects().size() / 4,
-					controller.getScale() * s.getObjects().size() / 4);
-			k += 1;
-			i += 20;
+	// check if body would collide with any other body
+	private boolean checkCollison(int i) {
+		boolean collision = false;
+		int r1 = (subnets.get(i - 1).getObjects().size() * 8) / 2;
+		int r2 = 1;
+		for (int j = 0; j < N; j++) {
+			if (j != i) {
+				int dist = (int) (Math.pow(rx - bodies.get(j).rx, 2) + Math.pow(ry - bodies.get(j).ry, 2));
+				if (j != 0)
+					r2 = (subnets.get(j - 1).getObjects().size() * 8) / 2;
+
+				if (Math.pow(r2 - r1, 2) <= dist && dist <= Math.pow(r2 + r1, 2)) {
+					collision = true;
+				}
+			}
 		}
+		return collision;
 	}
+
+	@Override
+	public void actionPerformed(ActionEvent arg0) {
+		repaint();
+	}
+
+	// calculate center of canvas for center gravity
+	public void calcCenter() {
+		center = this.getSize();
+		center.height /= 2;
+		center.width /= 2;
+	}
+
 }