Estoy haciendo algo que establece elementos similares a lo que Mac OS X hace con Windows en Exposé. Se adapta a la relación de aspecto de los elementos y a la relación de aspecto del área disponible.Algoritmo de diseño de Exposé
Básicamente, el área disponible se divide en filas y columnas. Se coloca un elemento en cada celda (la intersección de una fila y columna). Los elementos deben mantener su relación de aspecto (aquí width/height
) a pesar de la relación de aspecto de la celda. El número de celdas debe ser mayor o igual que el número de elementos. En el caso en que la cantidad de celdas sea mayor que la cantidad de elementos, la última fila no se utilizará por completo. El objetivo es tener la mayor cantidad de área disponible utilizada por los elementos como sea posible. Estoy bastante seguro de que cuanto más se aproxime la relación de aspecto de cada celda a la relación de aspecto del elemento, mejor.
Los siguientes funciona bien cuando la relación de aspecto del área disponible de es igual a las relaciones de aspecto de los artículos:
rows := round(sqrt(count));
columns := ceiling(sqrt(count));
Donde: count
es el número de elementos; round(x)
redondea x
al valor integral más cercano, redondeando casos a medio camino de cero; y ceiling(x)
devuelve el valor integral más pequeño no menos de x
.
Sé Compiz utiliza el siguiente algoritmo similar, pero no tiene en cuenta las relaciones de aspecto de los artículos y área disponible:
rows := floor(sqrt(count + 1));
columns := ceiling(count/rows);
Dónde: floor(x)
devuelve el mayor valor entero no mayor de x
.
Armado el siguiente algoritmo O (n) que prueba cada combinación de filas y columnas y busca el mejor ajuste, pero seguramente hay un algoritmo O (1) ya que produce exactamente los mismos resultados que el primero (O (1)) algoritmo cuando las relaciones de aspecto de los artículos y área disponible son los mismos:
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);
}
Donde: abs(x)
devuelve el valor absoluto de x
.
NOTA: Usted puede notar que esto no está optimizado en absoluto
Así que, ¿cuál es la mejor manera de tener disponible la zona más utilizada por los elementos como sea posible? (En otras palabras, ¿cómo puedo encontrar el mejor ajuste?)
Cualquier información sería agradable ... No puedo averiguar qué investigar, parece que no puedo encontrar nada. Solo un nombre común para el problema funcionaría. – vedosity
sin un conocimiento previo de que tendría que mirar al menos las dimensiones de todos, por lo que ya sería O (n). No veo ninguna manera razonable de hacerlo O (1) a menos que tenga información adicional. – lijie
Todos los elementos tienen la misma relación de aspecto y pueden cambiar de tamaño siempre que su relación de aspecto sea la misma. Podrías mirarlo ya que su ancho sería la relación de aspecto y su altura sería 1, por lo que las dimensiones son valores conocidos. – vedosity