2009-08-25 14 views
6

Próbuję pozycjonować elementy wizualne, aby pokazać wzajemne relacje między nimi. Wygląda na automatyczny układ graficzny, algorytm sprężynowy odpowiada moim potrzebom. Chciałbym zaimplementować to w silverlight za pomocą C#, więc szukam próbek kodu lub linki do dobrych wyjaśnień teorii. Każda pomoc doceniona:Teoria sprężyny automatycznego układu wykresów

Odpowiedz

6

pisałem jakiś kod chwilę temu wykonać dynamiczny układy graficzne wykorzystujące C# i XNA (pełne źródło dostępne na żądanie).

Oto niektóre z najważniejszych funkcji:

 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; 
     } 

Wybierz dwie stałe w oparciu o jak szybko chcesz wykres zbieżne. Użyłem tych:

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

Ten kod jest dość oczywisty, ale proszę pytać, czy potrzebujesz czegoś. Zasadniczo wywołaj funkcję UpdateNodes() w pętli, a twój wykres będzie zbieżny w stanie minimalnej energii.

+0

Tylko uwaga: że "węzły [i] .Velocity * = .99f;" jest stałą tłumienia, co ułatwia zbieganie się wykresu. Zmniejsz tę wartość, aby zmniejszyć "sprężystość". –

+0

Chciałbym źródło ... [email protected] –

+0

na pewno, tutaj jest (jako spakowany projekt): http://staff.arson-media.com/preetum/uploads/springForceV0.zip Zauważ, że napisałem ten kod * całkiem * jakiś czas temu, więc istnieją niepotrzebnie zaciemnione regiony (jak region oznaczony "mouseStuff" w pętli aktualizacji). Mimo to wszystkie ważne elementy są obecne i funkcjonalne. (Jest trochę interakcji z myszą) –

Powiązane problemy