if have multi开发者_运维问答ples object, how to arrange it so that each number of object in row x column will form a near square?
exp:14 objects arrange to something like this:
0 0 0 0
0 0 0 0
0 0 0 0
0 0
Take the ceil of the square root?
in python:
import math
ceil(14**(.5))
Which returns:
>>> from math import ceil
>>> ceil(14**(.5))
4.0
Get the square root of the number of items:
n = 14 ^ 0.5 ~ 3.7417
Round up to the nearest integer:
n = ceil(14 ^ 0.5) = 4
Now simply arrange the items in rows of n items until you run out.
Given n
objects, the size of the resulting "square" is ceil(sqrt(n))
, with special shortcut cases for n = 0 (don't draw anything) or n = 1 (just a 1x1 square).
Also, the question title is a little misleading. You can never arrange N objects in an NxN square, unless N is 1.
That depends. Assuming that the number of columns should be equal to or greater than the number of rows then the following calculates the number of columns (in pseudo-code):
Ceiling(Sqrt(n))
where n
is the number of items.
If you wish to center the grid, you'll have to know how much rows you'll have ahead of time, this function (it's javascript but I think it should easily be ported to another language) will generate a grid of positions and supports centering and spacing.
In pseudo-code
columns = Ceiling(Sqrt(n))
rows = (columns - 1) if (Round(Sqrt(n)) < columns) else columns
If center
is false
, the function will generate something like this (o
is the origin):
+———————+
|oxx |
|xxx |
|xx |
| |
| |
+———————+
If center
is true
+———————+
| |
| xxx |
| xox |
| x |
| |
+———————+
Code
/**
* Creates a grid of positions for the given items count and size.
* It assumes items anchor are centered.
*
* @param {number} x - The grid x position
* @param {number} y - The grid y position
* @param {number} count - The number of positions you wish to create
* @param {number} size - The item size
* @param {boolean} [center=true] - If true wil center the grid according to `x`, `y`
* @param {number} [spacing=0] - Item spacing
* @return {Array.<{x: number, y: number}>} The generated positions
*/
export const makeGrid = (x, y, count, size, { center = true, spacing = 0 } = {}) => {
// avoid computing trivial cases
if (count === 0) return []
if (count === 1) return [{ x, y }]
const sqrt = Math.sqrt(count)
const columns = Math.ceil(sqrt)
const rows = Math.round(sqrt) < columns ? columns - 1 : columns
const sizeAndSpacing = size + spacing
let offsetX = x
let offsetY = y
// if grid is centered apply offset according to `columns` and `rows`
if (center === true) {
offsetX -= (columns - 1) * sizeAndSpacing * .5
offsetY -= (rows - 1) * sizeAndSpacing * .5
}
let column = 0
let row = 0
return _.range(count).map(() => {
// if we're on last row's first column and grid is centered
if (row === rows - 1 && column === 0 && center === true) {
// if last row's items doesn't completely fill the line
// we apply an extra offset to center them
const modulus = count % columns
if (modulus > 0) {
offsetX += (columns - modulus) * sizeAndSpacing * .5
}
}
const pos = {
x: offsetX + column * sizeAndSpacing,
y: offsetY + row * sizeAndSpacing,
}
column++
if (column === columns) {
column = 0
row++
}
return pos
})
}
精彩评论