float kPower2 = k * k;
// System.out.println( "Temperature : " + temperature + " Level : " +
// level + " Number of Nodes: " + graph.getGraphSize( level ) );
Vector2D difference = new Vector2D();
float length;
Grid grid = new Grid( k * 2, nodes );
List<DNVNode> potentialNodes;
// repulsive forces
for( DNVNode v : nodes )
{
v.setForce( 0, 0 );
potentialNodes = grid.getPotentialNodes( v );
for( DNVNode u : potentialNodes )
{
if( u != v )
{
difference.set( v.getPosition() );
difference.subtract( u.getPosition() );
length = difference.length();
// If two nodes are in exact same position
// then we need to do something to move them apart.
// Give them a small repelling force in random direction.
if( length == 0 )
{
difference.set( (float)Math.random(), (float)Math.random() );
length = difference.length();
}
if( length < k * 2 )
{
difference.normalize();
if( useNodeSize )
{
difference.dotProduct( repel( length, kPower2 * u.getRadius() ) );
}
else
{
difference.dotProduct( repel( length, kPower2 ) );
}
if( useNumberOfSubnodes )
{
difference.dotProduct( Math.max( u.getSubNodes().size(), 1 ) );
difference.dotProduct( Math.max( v.getSubNodes().size(), 1 ) );
}
v.getForce().add( difference );
}
}
}
}
// attractive forces
for( DNVEdge e : edges )
{
difference.set( e.getFrom().getPosition() );
difference.subtract( e.getTo().getPosition() );
length = difference.length();
if( useRestingDistance )
{
length = length - e.getRestingDistance();
length = length * e.getK();
difference.normalize();
difference.dotProduct( attract( length, k ) );
}
else
{
difference.dotProduct( attract( length, k ) );
}
if( e.getTo().getType().equals( "topic" ) || !e.getFrom().getType().equals( "topic" ) )
e.getFrom().getForce().subtract( difference );
if( !e.getTo().getType().equals( "topic" ) || e.getFrom().getType().equals( "topic" ) )
e.getTo().getForce().add( difference );
}
/*
* Vector2D center = GraphFunctions.getCenterOfGravity( nodes.iterator()
* ); for( DNVNode v : nodes ) { difference.set( center );
* difference.subtract( v.getPosition() ); v.getForce().add( difference
* ); }
*/
// apply the forces
for( DNVNode v : nodes )
{
if( v.getProperty( "pinned" ) == null || v.getProperty( "pinned" ).equals("false"))
{
difference.set( v.getForce() );
length = difference.length();
difference.normalize();
difference.dotProduct( Math.min( length, temperature ) );
v.move( difference, true, false );
// v.getPosition().setX( Math.min( width / 2.0f, Math.max(
// -width / 2.0f, v.getPosition().getX() ) ) );
// v.getPosition().setY( Math.min( height / 2.0f, Math.max(
// -height / 2.0f, v.getPosition().getY() ) ) );