/**
							 | 
						|
								 * Created by Alex on 2/10/14.
							 | 
						|
								 */
							 | 
						|
								
							 | 
						|
								var hierarchalRepulsionMixin = {
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								  /**
							 | 
						|
								   * Calculate the forces the nodes apply on eachother based on a repulsion field.
							 | 
						|
								   * This field is linearly approximated.
							 | 
						|
								   *
							 | 
						|
								   * @private
							 | 
						|
								   */
							 | 
						|
								  _calculateNodeForces: function () {
							 | 
						|
								    var dx, dy, distance, fx, fy, combinedClusterSize,
							 | 
						|
								      repulsingForce, node1, node2, i, j;
							 | 
						|
								
							 | 
						|
								    var nodes = this.calculationNodes;
							 | 
						|
								    var nodeIndices = this.calculationNodeIndices;
							 | 
						|
								
							 | 
						|
								    // approximation constants
							 | 
						|
								    var b = 5;
							 | 
						|
								    var a_base = 0.5 * -b;
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								    // repulsing forces between nodes
							 | 
						|
								    var nodeDistance = this.constants.physics.hierarchicalRepulsion.nodeDistance;
							 | 
						|
								    var minimumDistance = nodeDistance;
							 | 
						|
								    var a = a_base / minimumDistance;
							 | 
						|
								
							 | 
						|
								    // we loop from i over all but the last entree in the array
							 | 
						|
								    // j loops from i+1 to the last. This way we do not double count any of the indices, nor i == j
							 | 
						|
								    for (i = 0; i < nodeIndices.length - 1; i++) {
							 | 
						|
								
							 | 
						|
								      node1 = nodes[nodeIndices[i]];
							 | 
						|
								      for (j = i + 1; j < nodeIndices.length; j++) {
							 | 
						|
								        node2 = nodes[nodeIndices[j]];
							 | 
						|
								        if (node1.level == node2.level) {
							 | 
						|
								
							 | 
						|
								          dx = node2.x - node1.x;
							 | 
						|
								          dy = node2.y - node1.y;
							 | 
						|
								          distance = Math.sqrt(dx * dx + dy * dy);
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								          if (distance < 2 * minimumDistance) {
							 | 
						|
								            repulsingForce = a * distance + b;
							 | 
						|
								            var c = 0.05;
							 | 
						|
								            var d = 2 * minimumDistance * 2 * c;
							 | 
						|
								            repulsingForce = c * Math.pow(distance,2) - d * distance + d*d/(4*c);
							 | 
						|
								
							 | 
						|
								            // normalize force with
							 | 
						|
								            if (distance == 0) {
							 | 
						|
								              distance = 0.01;
							 | 
						|
								            }
							 | 
						|
								            else {
							 | 
						|
								              repulsingForce = repulsingForce / distance;
							 | 
						|
								            }
							 | 
						|
								            fx = dx * repulsingForce;
							 | 
						|
								            fy = dy * repulsingForce;
							 | 
						|
								
							 | 
						|
								            node1.fx -= fx;
							 | 
						|
								            node1.fy -= fy;
							 | 
						|
								            node2.fx += fx;
							 | 
						|
								            node2.fy += fy;
							 | 
						|
								          }
							 | 
						|
								        }
							 | 
						|
								      }
							 | 
						|
								    }
							 | 
						|
								  },
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								  /**
							 | 
						|
								   * this function calculates the effects of the springs in the case of unsmooth curves.
							 | 
						|
								   *
							 | 
						|
								   * @private
							 | 
						|
								   */
							 | 
						|
								  _calculateHierarchicalSpringForces: function () {
							 | 
						|
								    var edgeLength, edge, edgeId;
							 | 
						|
								    var dx, dy, fx, fy, springForce, distance;
							 | 
						|
								    var edges = this.edges;
							 | 
						|
								
							 | 
						|
								    // forces caused by the edges, modelled as springs
							 | 
						|
								    for (edgeId in edges) {
							 | 
						|
								      if (edges.hasOwnProperty(edgeId)) {
							 | 
						|
								        edge = edges[edgeId];
							 | 
						|
								        if (edge.connected) {
							 | 
						|
								          // only calculate forces if nodes are in the same sector
							 | 
						|
								          if (this.nodes.hasOwnProperty(edge.toId) && this.nodes.hasOwnProperty(edge.fromId)) {
							 | 
						|
								            edgeLength = edge.customLength ? edge.length : this.constants.physics.springLength;
							 | 
						|
								            // this implies that the edges between big clusters are longer
							 | 
						|
								            edgeLength += (edge.to.clusterSize + edge.from.clusterSize - 2) * this.constants.clustering.edgeGrowth;
							 | 
						|
								
							 | 
						|
								            dx = (edge.from.x - edge.to.x);
							 | 
						|
								            dy = (edge.from.y - edge.to.y);
							 | 
						|
								            distance = Math.sqrt(dx * dx + dy * dy);
							 | 
						|
								
							 | 
						|
								            if (distance == 0) {
							 | 
						|
								              distance = 0.01;
							 | 
						|
								            }
							 | 
						|
								
							 | 
						|
								            distance = Math.max(0.8*edgeLength,Math.min(5*edgeLength, distance));
							 | 
						|
								
							 | 
						|
								            // the 1/distance is so the fx and fy can be calculated without sine or cosine.
							 | 
						|
								            springForce = this.constants.physics.springConstant * (edgeLength - distance) / distance;
							 | 
						|
								
							 | 
						|
								            fx = dx * springForce;
							 | 
						|
								            fy = dy * springForce;
							 | 
						|
								
							 | 
						|
								            edge.to.fx -= fx;
							 | 
						|
								            edge.to.fy -= fy;
							 | 
						|
								            edge.from.fx += fx;
							 | 
						|
								            edge.from.fy += fy;
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								            var factor = 5;
							 | 
						|
								            if (distance > edgeLength) {
							 | 
						|
								              factor = 25;
							 | 
						|
								            }
							 | 
						|
								
							 | 
						|
								            if (edge.from.level > edge.to.level) {
							 | 
						|
								              edge.to.fx -= factor*fx;
							 | 
						|
								              edge.to.fy -= factor*fy;
							 | 
						|
								            }
							 | 
						|
								            else if (edge.from.level < edge.to.level) {
							 | 
						|
								              edge.from.fx += factor*fx;
							 | 
						|
								              edge.from.fy += factor*fy;
							 | 
						|
								            }
							 | 
						|
								          }
							 | 
						|
								        }
							 | 
						|
								      }
							 | 
						|
								    }
							 | 
						|
								  }
							 | 
						|
								};
							 |