2009-08-25 48 views
6

我試圖將實體視覺化以顯示彼此之間的關係。它看起來像自動圖形佈局,彈簧算法將適合我的需要。我想用c#在Silverlight中實現它,所以我正在尋找代碼示例,或鏈接到理論的很好的解釋。任何幫助讚賞自動圖形佈局彈簧理論

回答

6

我寫了一些代碼,前一段時間來執行動態使用C#和XNA的圖形佈局(可根據要求提供完整源代碼)。

下面是一些關鍵功能:

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

選擇根據你想如何快速的圖形收斂兩個常量。我使用這些:

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

該代碼是不言自明的,但隨時問你是否需要任何東西。基本上,在一個循環中調用UpdateNodes()函數,並且您的圖形將收斂於其最小能量狀態。

+0

請注意:「節點[i] .Velocity * = .99f;」是一個讓你的圖更容易聚合的衰減常數。爲了減少「彈性」而減少該值。 – 2009-08-25 04:43:41

+0

我想來源... [email protected] – 2009-08-25 04:46:42

+0

當然,這是(作爲一個壓縮項目):http://staff.arson-media.com/preetum/uploads/springForceV0.zip 請注意,我很早以前就編寫了這個代碼,所以有一些不必要的混淆區域(如更新循環中標記爲「mouseStuff」的區域)。儘管如此,所有重要的組成部分都是存在的並且是功能性的。 (還有一些與鼠標的互動性) – 2009-08-25 05:22:40