J'ai n articles rectangulaires avec un rapport d'aspect AITEM (x: y).
J'ai une zone d'affichage rectangulaire avec un rapport d'aspect Aperiew P>
Les éléments doivent être agencés dans une mise en page similaire à une table (I.E. R lignes, Colonnes C). P>
Quelles sont les lignes de grille idéales x colonnes, de sorte que les articles individuels sont plus importants? (rangées * colums> = n, bien sûr - c'est-à-dire des lieux de grille "inutilisés"). p>
Un simple algorithme pourrait itération sur des lignes = 1..n, calculer le nombre de colonnes requis et conserver la paire de lignes / colonne avec les plus grands objets. p>
Je me demande s'il y a un algorithme non itératif, bien que (par exemple pour AITEM = AITEM = AITEW = 1, les rangées / cols peuvent être approchées par SQRT (N)). P>
4 Réponses :
bonne question. Si votre vue a des dimensions A x B (fixes) et vos éléments ont des dimensions A x B (variable, à optimiser), vous avez besoin de: p>
Je n'ai aucune idée de la façon de résoudre cependant - la trunc est la partie délicate, car elle est non linéaire. P> Trunc (A / A) * TRUNC (B / B)> = N CODE> P>
Votre solution peut être facilement améliorée pour gérer le boîtier générique: P>
Si nous [temporaires) oublient la nécessité d'avoir un nombre entier de lignes et de colonnes, nous avons p>
lignes * colonnes = n p>
x = aitem * y p>
AVIEW = lignes * x = lignes * aitem * y p>
1 = colonnes * y = (n / rangs) * (AVIEW / [lignes AITM *]) = N * AVIEW / (AITEM * ROWS²) P>
d'où rangées = sqrt (n * aview / aitem) et colonnes = n / rangs = sqrt (N * AITEM / AVIEW) P>
puis le plafond (rangées) et le plafond (colonnes) sont une solution pendant que le sol (rangées) et le plancher (colonnes) sont trop petits pour être une solution ensemble (si des rangées et des colonnes ne sont pas des entiers). Cela laisse 3 solutions possibles: P>
édité fort> pour corriger les équations. Le premier résultat était faux (voir Commentaires) P>
Je pense [aitem * une vue] dans vos dernières équations est une faute de frappe. Qu'en est-il du cas où n = 2, une vue = 6, élément = 3. Vous vous retrouveriez avec trop de colonnes.
Ce n'est pas une faute de frappe. C'est une erreur dans les premières équations, où j'ai pris des définitions opposées d'APRIEW et AITEM. Il est embarrassant car ma formule initiale n'était pas homogène (oui, je suis un physicien) et l'erreur apparaît sur un cas de test simple. Merci de le pointer. Maintenant, nous avons 2 lignes et 1 colonne pour votre témoignage, comme prévu
Remarque: Je ne pouvais pas tout à fait comprendre la réponse de Frédy Ric, alors j'ai travaillé le problème moi-même et j'ai proposé ce qui semble être la même solution. Je pensais que je pourrais aussi bien expliquer ce que j'ai fait au cas où il serait utile.
J'ai d'abord normalisé le rapport d'aspect de la vue sur celle des articles. (Je suppose que vous ne voulez pas faire pivoter les objets.) P> emballage maintenant un rapport rectangle de largeur / hauteur où multiplier / diviser ces deux équations nous donne p> A code> avec des carrés équivaut à emballer la vue avec des éléments. Le cas idéal serait pour notre grille (de carrés maintenant) de remplir complètement le rectangle, ce qui nous donnerait p>
r code> et
C code> sont les nombres de lignes et de colonnes: p>
r code> et
c code> sera des entiers, mais sinon, vous devez essayer les trois options d'options mentionnées et conserver la seule. où
r * c code> est le plus petit mais reste plus que
n code>: p>
étage (r), plafond (c) code> li>
plafond (r), plancher (c) code> li>
CEIL (R), CEIL (C) CODE> LI>
ul> p>
Merci pour vos commentaires détaillés. J'ai toujours des cas où la recherche de la force brute "a l'air mieux" que ces résultats de la vôtre / la suggestion de Frederics. Peut-être que je suis toujours soméhign Wrogn avec arrondir, bien que ... je joue avec ce seul temps partiel.
Une décennie plus tard, mais cette réponse m'a sauvé beaucoup de problèmes et rendait le programme dans ma tête possible. Merci beaucoup.
Je n'ai pas pu obtenir les réponses à cette question au travail pour moi, mais j'ai trouvé une mise en œuvre soignée à une question similaire de Neptilo . Cela n'a pas fonctionné pour les rectangles, mais seulement des carrés. J'ai donc appliqué l'idée de MCkeed pour normaliser le rectangle, puis suivez l'algorithme pour les carrés.
Le résultat est le par exemple et pour s'adapter 10 carrés dans le même exemple de la zone de 1920x1080, vous pouvez appeler FITOCONTAINER () CODE> Fonction. Donnez-lui le nombre de rectangles à adapter
n code>, le
conteneurwidth code> et
conteneurheight code> et l'original
itemWidth code> et
et
Itemheight code>. Dans le cas d'éléments n'a pas de largeur et de hauteur d'origine, utilisez
itemWidth code> et
itemheight code> pour spécifier le rapport souhaité des éléments. P>
fittocontainer (10, 1920, 1080, 16, 9) Code> Résultats dans
{NRows: 4, NCOLS: 3, itemWidth: 480, itemHeight: 270} code>, donc quatre colonnes et 3 lignes de 480 x 270 (pixels, ou quelle que soit l'unité). P>
FittOContainer (10, 1920, 1080, 1, 1) résultant de
{NRows: 2, NCOLS: 5, itemWidth: 384, ItemHeight: 384} Code>. P>
function fitToContainer(n, containerWidth, containerHeight, itemWidth, itemHeight) {
// We're not necessarily dealing with squares but rectangles (itemWidth x itemHeight),
// temporarily compensate the containerWidth to handle as rectangles
containerWidth = containerWidth * itemHeight / itemWidth;
// Compute number of rows and columns, and cell size
var ratio = containerWidth / containerHeight;
var ncols_float = Math.sqrt(n * ratio);
var nrows_float = n / ncols_float;
// Find best option filling the whole height
var nrows1 = Math.ceil(nrows_float);
var ncols1 = Math.ceil(n / nrows1);
while (nrows1 * ratio < ncols1) {
nrows1++;
ncols1 = Math.ceil(n / nrows1);
}
var cell_size1 = containerHeight / nrows1;
// Find best option filling the whole width
var ncols2 = Math.ceil(ncols_float);
var nrows2 = Math.ceil(n / ncols2);
while (ncols2 < nrows2 * ratio) {
ncols2++;
nrows2 = Math.ceil(n / ncols2);
}
var cell_size2 = containerWidth / ncols2;
// Find the best values
var nrows, ncols, cell_size;
if (cell_size1 < cell_size2) {
nrows = nrows2;
ncols = ncols2;
cell_size = cell_size2;
} else {
nrows = nrows1;
ncols = ncols1;
cell_size = cell_size1;
}
// Undo compensation on width, to make squares into desired ratio
itemWidth = cell_size * itemWidth / itemHeight;
itemHeight = cell_size;
return { nrows: nrows, ncols: ncols, itemWidth: itemWidth, itemHeight: itemHeight }
}