第一个朴素算法,我们“推送”与另一个图标重叠的图标:
FOR iconToPlace in icons do:
isPlaced = false
WHILE(not isPlaced) DO:
isPlaced = true
FOR icon in icons DO:
IF overlap(iconToPlace, icon) AND iconToPlace != icon THEN:
isPlaced = false
push(iconToPlace) // same angle but the icon is now further
BREAK
ENDIF
ENDFOR
ENDWHILE
ENDFOR
使用第一个算法,一些图标将比其他图标离中心更远。但它并没有通过改变角度来利用可能的位置。通过将此应用于您的第二个设计(具有小值),很明显该解决方案将远离理想的解决方案。
第二个不那么天真的算法,首先我们为每个图标分配一个新的角度(差异小于 DeltaAngleMax),然后我们应用第一个算法:
icons = SORT(icons)
iconsRef = icons
isFinished = false
WHILE(not isFinished) DO:
isFinished = true
FOR i = 0 TO i = NUM_ICONS-1 DO:
IF overlap(icons(i), icons(i+1 % NUM_ICONS))
AND not overlap(icons(i), icons(i-1 % NUM_ICONS)) //seems useless
AND not overlap(icons(i)-DeltaAngle % 360, icons(i-1 % NUM_ICONS))
AND ABS(icons(i)-iconsRef(i)) <= DeltaAngleMax THEN:
//overlap with next icon but not with previous,
//if we decrease angle we still not overlap with previous icon and
//the futur delta angle is less than DeltaAngleMax
//then we can move the icon :
icons(i) = icons(i)-DeltaAngle
isFinished = false
ELSE IF overlap(icons(i), icons(i-1 % NUM_ICONS))
AND not overlap(icons(i), icons(i+1 % NUM_ICONS)) //seems useless
AND not overlap(icons(i)+DeltaAngle % 360, icons(i+1 % NUM_ICONS))
AND ABS(icons(i)-iconsRef(i)) <= DeltaAngleMax THEN:
//vice et versa:
icons(i) = icons(i)+DeltaAngle
isFinished = false
ENDFOR
ENDWHILE
APPLY_FIRST_ALGO
明智地选择 deltaAngle 和 DeltaAngleMax。太小的 deltaAngle 会导致运行时间过长。
为了更进一步,您应该查看力导向图形绘制算法,这是实现目标的更强大的方法,其中一个困难是找到节点的正确力(您的图标,您没有边缘)。