FDA算法,Force Directed Algorithm,一种点线图的布局算法,找了半天没有有关描述,只有根据原始英文文档的理解写一下。

定义:

  • area=W*L WL为画布的宽度和长度

  • V 点集  E 边集

  • k = sqrt(area/|V|)

  • fa(z) = z*z/k

  • fr(z) = k*k/z

   k为点密度的开根号。

   fa计算了相关的点点距离平方除以k,该算式用来计算引力,距离越大,引力越恐怖,同时,点越多越容易被吸引到有连线的点周围。

   fr计算不相关的点斥力,点密度除以点距离,距离越远斥力越小,点越多被推开的距离越近。连线对点的影响更大,相关的点计算引力时使用了距离的平方,而不相关的在计算斥力时计算的结果总是相对较小的。


对每个点v

   对每个不和v相连的点u做如下运算:

       e = v.pos-u.pos

       v.disp = v.disp+(e/|e|)*fr(|e|)

   每个点包含了两个向量 pos 位置向量 和 disp位移向量。

   所以,e为两点连线的向量。

   由此,第二个表达式可解释为:v点被推离u点方向,推开距离为fr(|e|),也就是 点密度/点距离。推开方向为e/|e|。

FDA算法_FDA

   上图仅作简要示意,把点的独占面积拉长或者压缩成矩形,其中一个边长是点间距,另一个边长就是斥力导致的位移距离。


对每个边上的两点u和v

   对每个和v相连的点u作如下操作:

       e = v.pos-u.pos

       v.disp = v.disp-(e/|e|)*fa(|e|)

       u.disp = u.disp+(e/|e|)*fa(|e|)

   同样,e为两点连线的向量

   由此,v点被吸引向u点方向,吸引距离fa(|e|)也就是 距离平方 除以 点独占面积开根号。有利于距离远的相连点快速吸引到周围。方向为e/|e|。

FDA算法_Layout_02

   简要示意图,点间距做边长的正方形s1,点独占面积虚拟成的正方形s2,将s1拉长或者压缩成其中一边长为s2边长的等面积矩形s3。引力造成的位移距离就是s3的另一边长。

   最后,算法将做n次迭代,每次都计算一下每个点与不相邻点的斥力以及每个边所引入的引力,迭代次数越多,点的聚集性会越明显。这只是FDA的简单描述,还需要添加画布大小的控制,确保点不会被推出画布。