2009-08-25 7 views
6

Estoy tratando de ubicar las entidades visualmente para mostrar sus relaciones entre sí. Parece que el diseño gráfico automático, el algoritmo de primavera se adapte a mis necesidades. Me gustaría implementar esto en Silverlight usando C#, entonces estoy buscando ejemplos de código o enlaces a buenas explicaciones de la teoría. Cualquier ayuda apreciadaTeoría automática de la primavera del diseño gráfico

Respuesta

6

escribí algo de código hace un rato para realizar dinámico diseños de gráficos usando C# y XNA (fuente completa disponible a pedido).

Estas son algunas de las funciones críticas:

 public void UpdateNodes() 
     { 
      for (int i = 0; i < nodes.Count; i++) 
      { 
       Vector2 netForce = Vector2.Zero; 
       foreach (Node otherNode in nodes) 
       { 
        if (otherNode != nodes[i]) 
        { 
         netForce += CoulombRepulsion(nodes[i], otherNode); //calculate repulsion for all nodes 
         if (nodes[i].links.Contains(otherNode)) 
         { 
          netForce += HookeAttraction(nodes[i], otherNode); //only calc attraction for linked nodes 
         } 
        } 
       } 
       nodes[i].Velocity += netForce; 
       nodes[i].Velocity *= .99f; 
       nodes[i].Position += nodes[i].Velocity; 
      } 
     } 


     public Vector2 HookeAttraction(Node node1, Node node2) //ON node1 BY node2 
     { 
      Vector2 direction = Vector2.Subtract(node2.Position, node1.Position); 
      direction.Normalize(); 

      return hookeConst* node2.Mass * Vector2.Distance(node1.Position, node2.Position) * direction; 
     } 

     public Vector2 GravAttraction(Node node1, Node node2) //ON node1 BY node2 
     { 
      Vector2 direction = Vector2.Subtract(node2.Position, node1.Position); 
      direction.Normalize(); 

      return gravConst * node2.Mass * Vector2.DistanceSquared(node1.Position, node2.Position) * direction; 
     } 

escoger las dos constantes en base a la rapidez con que desea que el gráfico que converja. Utilicé estos:

 private const float hookeConst = .000005f; 
     private const float gravConst = .00000001f; 

Ese código es bastante autoexplicativo, pero no dude en preguntar si necesita algo. Básicamente, llame a la función UpdateNodes() en un bucle, y su gráfico convergerá en su estado de energía mínima.

+0

Solo una nota: que "nodos [i] .Velocity * = .99f;" es una constante de amortiguación para hacer que su gráfico converja más fácilmente. Disminuya ese valor por menos "elasticidad". –

+0

Me gustaría que la fuente ... [email protected] –

+0

seguro, aquí está (como un proyecto comprimido): http://staff.arson-media.com/preetum/uploads/springForceV0.zip Tenga en cuenta que escribí este código * bastante * hace un tiempo, por lo que hay algunas regiones innecesariamente ofuscadas (como la región marcada como "mouseStuff" en el ciclo de actualización). Sin embargo, todos los componentes importantes están presentes y son funcionales. (También hay algo de interactividad con el mouse) –

Cuestiones relacionadas