@@ -9,6 +9,8 @@ struct ForceDirectedLayoutEngine: LayoutEngine {
99 var springLength : CGFloat = 70
1010 var stiffness : CGFloat = 0.09
1111 var charge : CGFloat = 50
12+ var gravitationalConstant = CGFloat ( 20 )
13+ var shieldDistanceSquared = CGFloat ( 250000 )
1214
1315 func layout( from currentLayout: Layout ,
1416 canvas: CGRect ,
@@ -22,6 +24,7 @@ struct ForceDirectedLayoutEngine: LayoutEngine {
2224 for (index, position) in positions. enumerated ( ) {
2325 forces [ index] += repulsionForce ( at: position, from: positions, skipIndex: index)
2426 forces [ index] += springForce ( at: position, from: edges [ index] )
27+ forces [ index] += centralForce ( at: position, from: canvas. center)
2528
2629 let nv = velocities [ index] + forces[ index]
2730 let d = nv. length
@@ -57,9 +60,19 @@ struct ForceDirectedLayoutEngine: LayoutEngine {
5760 guard index != skippedIndex else { continue }
5861
5962 let diff = point - other
60- force += diff / ( diff. lengthSquared + 0.00000001 ) * charge
63+ let diffSquared = diff. lengthSquared
64+ guard diffSquared < shieldDistanceSquared else {
65+ continue
66+ }
67+ force += diff / ( diffSquared + 0.00000001 ) * charge
6168 }
6269
6370 return force
6471 }
72+
73+ private func centralForce( at point: CGPoint , from center: CGPoint ) -> CGPoint {
74+ let diff = center - point
75+ let dist = diff. lengthSquared
76+ return dist > shieldDistanceSquared ? diff / dist * gravitationalConstant : . zero
77+ }
6578}
0 commit comments