2010-12-14 27 views
8

Exposé'de Mac OS X'in Windows'la yaptığı öğelere benzer öğeler koyarım. Öğelerin en boy oranına ve mevcut alanın en boy oranına uyarlanır.Exposé Layout Algorithm

Temel olarak, kullanılabilir alan satırlara ve sütunlara bölünür. Her bir hücreye bir öğe konur (bir satır ve sütunun kesişmesi). Öğeler, hücrenin en boy oranına rağmen en boy oranını (burada width/height) korumalıdır. numaralı hücrelerin sayısı, olmalıdır, öğe sayısına eşit veya daha büyük olmalıdır. Hücre sayısının öğe sayısından fazla olduğu durumda, son satır tam olarak kullanılmayacaktır. Amaç, mümkün olduğunca ürün tarafından kullanılan kullanılabilir alana sahip olmaktır. Eminim her hücrenin en-boy oranı nesnenin en-boy oranına ne kadar yakın olursa, o kadar iyi olur.

uygun bölgenin en-boy oranı, ürün boy oranlarına eşittir da belirtilen çalışmaları:

rows := round(sqrt(count)); 
columns := ceiling(sqrt(count)); 

: count öğelerin sayısı olduğu; round(x)x, en yakın integral değere yuvarlar; ve ceiling(x), x'dan küçük olmayan en küçük ayrılmaz değeri döndürür. floor(x) büyük ayrılmaz değeri büyük olmayan x daha döndürür:

rows := floor(sqrt(count + 1)); 
columns := ceiling(count/rows); 

: öğeleri ve mevcut alanın boy oranları Ben Compiz'i biliyorum

aşağıdaki benzer bir algoritma kullanır, ancak dikkate almaz .

Her bir satır ve sütun birleşimini sınayan ve en uygun olanı arayan aşağıdaki O (n) algoritmasını bir araya getirdim, ancak kesinlikle bir O (1) algoritması var. (1)) algoritması öğeleri ve mevcut alanı en boy oranları aynı olduğunda:

fit (itemCount, itemRatio, availableRatio) 
{ 
    bestRows := infinity; 
    bestColumns := infinity; 
    bestDiff := infinity; 

    for (rows := 1; rows <= count; rows += 1) 
    { 
     columns := ceiling(count/rows); 

     cellWidth := availableRatio/columns; 
     cellHeight := 1.0/rows; 
     cellRatio := cellWidth/cellHeight; 

     diff := abs(cellRatio - itemRatio); 

     if (diff < bestDiff) 
     { 
      bestRows := rows; 
      bestColumns := columns; 
      bestDiff := diff; 

      if (diff = 0) 
       break; 
     } 
    } 

    return (bestRows, bestColumns); 
} 

Burada: x mutlak değerini verir abs(x).

NOT: olabildiğince öğeleri tarafından kullanılan en uygun alana sahip en iyi yolu nedir, bu nedenle tüm

de optimize edilmemiştir fark edebilirsiniz? (Diğer bir deyişle, nasıl en uygun bulurum?)

+0

Herhangi bir bilgi güzel olurdu .. Ne araştırma yapacağımı anlayamıyorum, hiçbir şey bulamıyorum. Sorun için sadece ortak bir isim işe yarayacaktı. Apriori bilgisi olmadan – vedosity

+0

en azından herkesin boyutlarına bakmanız gerekecek, bu yüzden zaten O (n) olacaktır. Daha fazla bilgi almadıkça O (1) yapmak için makul bir yol göremiyorum. – lijie

+0

Öğelerin hepsi aynı en boy oranına sahiptir ve en boy oranları aynı olduğu sürece yeniden boyutlandırabilir. Genişlikleri en boy oranı olacak ve boyları 1 olacaktır, bu yüzden boyutlar bilinen değerlerdir. – vedosity

cevap

0

Sen

  1. hiçbir yatay boşluk

Tamam hiçbir dikey boşluk ile öğeleri paketi olabilir, en olmadan toplamama izin dikey boşluk.Daha sonra yatay bir boşluktur:

Gh = nrows * availRatio - ncolumns * itemRatio 

ya da N ile yazılmış

Gh = x * availRatio - N * itemRatio/x 

Gh

x² = N * itemRatio/availRatio 
x = sqrt(N * itemRatio/availRatio) 

0'a yakın olan Eğer hücrelerinin, kontrol etmek (x) ve taban (x) ve y = taban (N/x)

Yatay boşluk olmadan ambalaj verimleri:

y = sqrt(N * availRatio/itemRatio) 

için hücrelerinin, (y) ve taban (Y) kontrol etmek ve x = taban (N/y)

nedenle boşluktaki kontrol etmek için en fazla 4 kombinasyonları bulunmaktadır. Sonra bunu en küçük pozitif boşlukla seçin.

fit (itemCount, itemRatio, availableRatio) { 
    x := sqrt(itemcount * itemRatio/availableRatio); 
    x1 := floor(x); 
    y1 := ceil(itemCount/x1); 
    x2 := ceil(x); 
    y2 := ceil(itemCount/x2); 

    y := sqrt(itemcount * availableRatio/itemRatio); 
    y3 := floor(x); 
    x3 := ceil(itemCount/y3); 
    y4 := ceil(x); 
    x4 := ceil(itemCount/y4); 

    gap := y1 * availableRatio - x1 * itemRatio; 
    x := x1; 
    y := y1; 

    gap2 := y2 * availableRatio - x2 * itemRatio; 
    if (gap2 >= 0 && gap2 < gap || gap < 0) { 
     gap := gap2; 
     x := x2; 
     y := y2; 
    } 

    gap3 := x3 * itemRatio/availRatio - y3; 
    if (gap3 >= 0 && gap3 < gap || gap < 0) { 
     gap := gap3; 
     x := x3; 
     y := y3; 
    } 

    gap4 := x4 * itemRatio/availRatio - y4; 
    if (gap4 >= 0 && gap4 < gap || gap < 0) { 
     gap := gap4; 
     x := x4; 
     y := y4; 
    } 

    return (x, y); 
} 

yerine boşluğu kullanmanın da son satırın beri/sütun çok iyi doldurulmamış olabilir, karar vermek için çok az alan kullanabilirsiniz.

İlgili konular