頭一個幼稚的算法,我們以「推」與另一圖標重疊圖標:
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
有了這個第一算法一些圖標會futher從中心以外。但它沒有通過改變角度來利用可能的地方。通過將其應用於第二個設計(具有較小的值),顯然該解決方案將遠離理想的解決方案。
第二少幼稚算法中,首先我們分配一個新的角度(大於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會導致很大的運行時間。
要走得更遠,你應該看看the force-directed graph drawing算法,這是更健壯的方法來實現你的目標,其中一個難點是找到節點的正確力量(你的圖標,你沒有邊緣)。
這不是最好的解決方案,但它足夠好並且很容易實現。對於閱讀此內容的人,請閱讀其他答案。 – Sulthan 2013-05-23 10:51:39
蘇丹 - 你好,你在乎分享完整的解決方案嗎?我會非常感謝代碼本身,我確實需要它的Android,但iOS的例子也將作爲一個很好的參考。 – sahar 2017-05-16 14:10:49