English 中文(简体)
如何确定任意数量的相等正方形的大小,以适合固定大小的2D空间?
原标题:How do I determine the size of an arbitrary number of equal squares to be fit into an fixed size 2D space?
  • 时间:2011-05-28 20:37:49
  •  标签:
  • algorithm

我有一个固定大小的2D空间,我想用任意数量的相等大小的正方形来填充。我想要一个算法来确定这些正方形的确切大小(一侧的长度),以便完美地适应给定的空间。

最佳回答

请注意,必须有整数个正方形来填充宽度和高度。因此,纵横比必须是一个有理数。

输入:width(float或int),height

算法:

aspectRatio = RationalNumber(width/height).lowestTerms  #must be rational number

# it must be the case that our return values
# numHorizontalSqaures/numVerticalSquares = aspectRatio

return {
    numHorizontalSquares = aspectRatio.numerator,
    numVerticalSquares = aspectRatio.denominator,
    squareLength = width/aspectRatio.numerator
}

如果宽度/高度是一个有理数,那么你的答案只是纵横比的任意倍数!(例如,如果你的纵横比是4/3,你可以用4x3个长width/4=height/3的正方形来填充,或者用8x6个一半大小的正方形,或者用12x9个三分之一大小的正方形…)如果它不是有理数,你的任务就不可能完成。

通过对分子和分母进行因子分解,并删除所有重复的因子对,可以将分数转换为最低项;这相当于只使用最大公约数算法GCD(numer,denom),并将分子和分母都除以它。

以下是python3中的一个示例实现:

from fractions import Fraction
def largestSquareTiling(width, height, maxVerticalSquares=10**6):
    """
        Returns the minimum number (corresponding to largest size) of square
        which will perfectly tile a widthxheight rectangle.

        Return format:
            (numHorizontalTiles, numVerticalTiles), tileLength
    """
    if isinstance(width,int) and isinstance(height,int):
        aspectRatio = Fraction(width, height)
    else:
        aspectRatio = Fraction.from_float(width/height)

    aspectRatio2 = aspectRatio.limit_denominator(max_denominator=maxVerticalSquares)
    if aspectRatio != aspectRatio2:
        raise Exception( too many squares ) #optional
    aspectRatio = aspectRatio2

    squareLength = width/aspectRatio.numerator
    return (aspectRatio.numerator, aspectRatio.denominator), squareLength

例如。

>>> largestSquareTiling(2.25, 11.75)
((9, 47), 0.25)

You can tune the optional parameter maxVerticalSquares to give yourself more robustness versus floating-point imprecision (but the downside is the operation may fail), or to avoid a larger number of vertical squares (例如。 if this is architecture code and you are tiling a floor); depending on the range of numbers you are working with, a default value of maxVerticalSquares=500 might be reasonable or something (possibly not even including the exception code).

一旦你有了这个,以及一个所需的平方长度范围(minLength,maxLength),你只需要乘以:

# inputs    
desiredTileSizeRange = (0.9, 0.13)
(minHTiles, minVTiles), maxTileSize = largestSquareTiling(2.25, 11.75)

# calculate integral shrinkFactor
shrinkFactorMin = maxTileSize/desiredTileSizeRange[0]
shrinkFactorMax = maxTileSize/desiredTileSizeRange[1]
shrinkFactor = int(scaleFactorMax)
if shrinkFactor<shrinkFactorMin:
    raise Exception( desired tile size range too restrictive; no tiling found )

例如,如果shrinkFactor现在为2,则示例中的新输出值将为((9*2,47*2),0.25/2)

问题回答

如果边是整数,则需要找到a和B边之间的最大公约数,即您要查找的正方形边。

您希望使用空间填充曲线或空间索引。sfc递归将平面细分为4个瓦片,并将2d复杂度降低为1d复杂度。你想找尼克的希尔伯特曲线四叉树空间索引博客。

我想这就是你想要的。至少它解决了我发现这个问题时在谷歌上搜索的问题。

// width = width of area to fill
// height = height of area to fill
// sqareCount = number of sqares to fill the area with
function CalcSquareSide(float width, float height, int squareCount)
{
  return Math.Sqrt((height * width) / squareCount);
}




相关问题
How to add/merge several Big O s into one

If I have an algorithm which is comprised of (let s say) three sub-algorithms, all with different O() characteristics, e.g.: algorithm A: O(n) algorithm B: O(log(n)) algorithm C: O(n log(n)) How do ...

Grokking Timsort

There s a (relatively) new sort on the block called Timsort. It s been used as Python s list.sort, and is now going to be the new Array.sort in Java 7. There s some documentation and a tiny Wikipedia ...

Manually implementing high performance algorithms in .NET

As a learning experience I recently tried implementing Quicksort with 3 way partitioning in C#. Apart from needing to add an extra range check on the left/right variables before the recursive call, ...

Print possible strings created from a Number

Given a 10 digit Telephone Number, we have to print all possible strings created from that. The mapping of the numbers is the one as exactly on a phone s keypad. i.e. for 1,0-> No Letter for 2->...

Enumerating All Minimal Directed Cycles Of A Directed Graph

I have a directed graph and my problem is to enumerate all the minimal (cycles that cannot be constructed as the union of other cycles) directed cycles of this graph. This is different from what the ...

Quick padding of a string in Delphi

I was trying to speed up a certain routine in an application, and my profiler, AQTime, identified one method in particular as a bottleneck. The method has been with us for years, and is part of a "...

热门标签