Package net.wigis.graph.dnv.layout.implementations

Source Code of net.wigis.graph.dnv.layout.implementations.HopDistanceLayout

/******************************************************************************************************
* Copyright (c) 2010, University of California, Santa Barbara
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
*    * Redistributions of source code must retain the above copyright notice, this list of
*      conditions and the following disclaimer.
*    * Redistributions in binary form must reproduce the above copyright notice, this list of
*      conditions and the following disclaimer in the documentation and/or other materials
*      provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*****************************************************************************************************/

package net.wigis.graph.dnv.layout.implementations;

import java.io.BufferedWriter;
import java.util.List;

import net.wigis.graph.dnv.DNVEdge;
import net.wigis.graph.dnv.DNVGraph;
import net.wigis.graph.dnv.DNVNode;
import net.wigis.graph.dnv.layout.helpers.Grid;
import net.wigis.graph.dnv.layout.interfaces.NodeCentralizedLayoutInterface;
import net.wigis.graph.dnv.utilities.GraphFunctions;
import net.wigis.graph.dnv.utilities.Vector2D;

// TODO: Auto-generated Javadoc
/**
* The Class HopDistanceLayout.
*
* @author Brynjar Gretarsson
*/
public class HopDistanceLayout implements NodeCentralizedLayoutInterface
{

  /**
   * Run layout.
   *
   * @param graph
   *            the graph
   * @param centralNode
   *            the central node
   * @param level
   *            the level
   * @param circle
   *            the circle
   */
  @Override
  public void runLayout( DNVGraph graph, DNVNode centralNode, int level, boolean circle )
  {
    for( DNVNode node : graph.getNodes( level ) )
    {
      node.removeProperty( "hopDistance" );
    }
    GraphFunctions.findShortestPathToAllNodesInNumberOfHops( centralNode );
    float maxDistance = 0;
    String hopDistance;
    float tempDistance;
    for( DNVNode node : graph.getNodes( level ) )
    {
      hopDistance = node.getProperty( "hopDistance" );
      if( hopDistance != null )
      {
        tempDistance = Float.parseFloat( hopDistance );
        if( tempDistance > maxDistance )
        {
          maxDistance = tempDistance;
        }
      }
    }
    maxDistance++;
    float width = GraphFunctions.getGraphWidth( graph, level, false );
    float height = GraphFunctions.getGraphHeight( graph, level, false );

    layoutLevel( width, height, graph, 0.01f, level, centralNode.getPosition(), circle, maxDistance );
  }

  /**
   * Layout level.
   *
   * @param width
   *            the width
   * @param height
   *            the height
   * @param graph
   *            the graph
   * @param coolingFactor
   *            the cooling factor
   * @param level
   *            the level
   * @param center
   *            the center
   * @param circle
   *            the circle
   * @param maxDistance
   *            the max distance
   */
  private static void layoutLevel( float width, float height, DNVGraph graph, float coolingFactor, int level, Vector2D center, boolean circle,
      float maxDistance )
  {
    float size = Math.max( GraphFunctions.getGraphWidth( graph, level, false ), width );
    size = Math.max( size, Math.max( GraphFunctions.getGraphHeight( graph, level, false ), height ) );
    float temperature = size / 4.0f;

    int counter = 0;
    while( temperature > 0 )
    {
      runIteration( width, height, graph, level, temperature, center, counter, circle, maxDistance );
      temperature = cool( temperature, coolingFactor );
      counter++;
    }

    for( DNVNode v : graph.getNodes( level ) )
    {
      forceToShape( v, center, circle, maxDistance );
    }
  }

  /**
   * Attract.
   *
   * @param x
   *            the x
   * @param k
   *            the k
   * @return the float
   */
  private static float attract( float x, float k )
  {
    return ( x * x ) / k;
  }

  /**
   * Repel.
   *
   * @param x
   *            the x
   * @param kPower2TimesRadiusU
   *            the k power2 times radius u
   * @return the float
   */
  private static float repel( float x, float kPower2TimesRadiusU )
  {
    return kPower2TimesRadiusU / x;
  }

  /**
   * Cool.
   *
   * @param temperature
   *            the temperature
   * @param coolingFactor
   *            the cooling factor
   * @return the float
   */
  private static float cool( float temperature, float coolingFactor )
  {
    if( temperature > 0.01 )
      return Math.max( 0, temperature * ( 1 - coolingFactor ) );

    return 0;
  }

  /**
   * Force to circle.
   *
   * @param v
   *            the v
   * @param center
   *            the center
   * @param maxDistance
   *            the max distance
   */
  private static void forceToCircle( DNVNode v, Vector2D center, float maxDistance )
  {
    float radius;
    try
    {
      String hopDistance = v.getProperty( "hopDistance" );
      if( hopDistance == null || hopDistance.equals( "" ) )
      {
        radius = maxDistance;
      }
      else
      {
        radius = Float.parseFloat( hopDistance );
      }
      v.getPosition().normalize().dotProduct( radius ).add( center );
      // if( v.getPosition().getX() < center.getX() )
      // {
      // v.getPosition().setX( center.getX() );
      // }
    }
    catch( NullPointerException npe )
    {
      npe.printStackTrace();
    }
  }

  /**
   * Force to shape.
   *
   * @param v
   *            the v
   * @param center
   *            the center
   * @param circle
   *            the circle
   * @param maxDistance
   *            the max distance
   */
  private static void forceToShape( DNVNode v, Vector2D center, boolean circle, float maxDistance )
  {
    if( circle )
      forceToCircle( v, center, maxDistance );
    else
      forceToLine( v, center, maxDistance );
  }

  /**
   * Force to line.
   *
   * @param v
   *            the v
   * @param center
   *            the center
   * @param maxDistance
   *            the max distance
   */
  private static void forceToLine( DNVNode v, Vector2D center, float maxDistance )
  {
    float radius;
    String hopDistance = v.getProperty( "hopDistance" );
    if( hopDistance == null || hopDistance.equals( "" ) )
    {
      radius = maxDistance;
    }
    else
    {
      radius = Float.parseFloat( hopDistance );
    }
    v.getPosition().setX( radius + center.getX() );
  }

  /**
   * Run iteration.
   *
   * @param width
   *            the width
   * @param height
   *            the height
   * @param graph
   *            the graph
   * @param level
   *            the level
   * @param temperature
   *            the temperature
   * @param center
   *            the center
   * @param counter
   *            the counter
   * @param circle
   *            the circle
   * @param maxDistance
   *            the max distance
   */
  public static void runIteration( float width, float height, DNVGraph graph, int level, float temperature, Vector2D center, int counter,
      boolean circle, float maxDistance )
  {
    synchronized( graph )
    {

      float area = width * height;
      float k = (float)Math.sqrt( area / graph.getGraphSize( level ) );
      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, graph, level );
      List<DNVNode> potentialNodes;

      // float maxYAtDistance1 = Float.NEGATIVE_INFINITY;
      // float minYAtDistance1 = Float.POSITIVE_INFINITY;
      // float tempY;
      // float distance;
      // repulsive forces
      for( DNVNode v : graph.getNodes( level ) )
      {
        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( length == 0 )
            {
              difference.set( (float)Math.random() - 0.5f, (float)Math.random() - 0.5f );
              length = difference.length();
            }
            if( length < k * 2 )
            {
              difference.normalize();
              difference.dotProduct( repel( length, kPower2 * u.getRadius() ) );
              v.getForce().add( difference );
            }
          }
        }
      }

      // attractive forces
      for( DNVEdge e : graph.getEdges( level ) )
      {
        difference.set( e.getFrom().getPosition() );
        difference.subtract( e.getTo().getPosition() );
        length = difference.length();
        difference.normalize();
        difference.dotProduct( attract( length, k ) );
        e.getFrom().getForce().subtract( difference );
        e.getTo().getForce().add( difference );
      }

      // apply the forces
      for( DNVNode v : graph.getNodes( level ) )
      {
        difference.set( v.getForce() );
        length = difference.length();
        difference.normalize();
        difference.dotProduct( Math.min( length, temperature ) );
        v.move( difference, true, false );
        if( counter % 5 == 0 )
        {
          forceToShape( v, center, circle, maxDistance );
        }
      }
    }
  }

  @Override
  public String getLabel()
  {
    return "Hop Distance Layout";
  }
  private BufferedWriter writer;
  @Override
  public void setOutputWriter(BufferedWriter writer) {
    // TODO Auto-generated method stub
    this.writer = writer;
  }

}
TOP

Related Classes of net.wigis.graph.dnv.layout.implementations.HopDistanceLayout

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.