【问题标题】:how to find distribution between two values如何找到两个值之间的分布
【发布时间】:2021-03-13 07:04:16
【问题描述】:

假设我有一个 210 毫米 x 297 毫米 (A4) 的页面。它的每边打印边距为 5 毫米。 我想打印 1cm x 1cm 的正方形来填满页面。每个正方形都有一个特定的边距,比如右边 1 毫米,底部 2 毫米。 现在计算我能得到多少平方很容易:

( 210 - 10 ) / ( 10 + 1 ) = 18.181...

( 297 - 10 ) / ( 10 + 2 ) = 23.916...

所以 23 行 18 列的正方形适合我的页面。


现在我希望第一行正方形为 1cm x 1cm,最后一行为 5mm x 5mm。

但是中间的所有行都应该用 5mm 的行填充。大小从上到下递减。

如何找到行数和每行的正方形大小?


我能想到的最好的,但需要尝试一步:

const heightAvailable = 287;
const maxSizeElement  = 10;
const minSizeElement  = 5;
const marginBottom    = 2;
const step            = 0.15;

function getElementsArray(availableLeft, minElement, maxElement, margin, step) {
  const elementsArray = [];
  elementsArray.push(minElement);
  elementsArray.push(maxElement);

  while(isSizeLeft(availableLeft, minElement, maxElement, margin)) {
    minElement+=step;
    maxElement-=step;
    elementsArray.push(Number((minElement).toFixed(1)));
    elementsArray.push(Number((maxElement).toFixed(1)));

    availableLeft = getSizeLeft(availableLeft, minElement, maxElement, margin);
  }

  return elementsArray.sort(function(a,b) { return b - a;});;
}

function isSizeLeft(total, minElement, maxElement, margin) {
  return 0 < total - (maxElement+margin) - (minElement+margin);
}

function getSizeLeft(total, minElement, maxElement, margin) {
  return total - (maxElement+margin) - (minElement+margin);
}

返回:

array(32) {
  [0]=>
  int(10)
  [1]=>
  float(9.9)
  [2]=>
  float(9.7)
  [3]=>
  float(9.6)
  [4]=>
  float(9.4)
  [5]=>
  float(9.3)
  [6]=>
  float(9.1)
  [7]=>
  float(9)
  [8]=>
  float(8.8)
  [9]=>
  float(8.7)
  [10]=>
  float(8.5)
  [11]=>
  float(8.4)
  [12]=>
  float(8.2)
  [13]=>
  float(8.1)
  [14]=>
  float(7.9)
  [15]=>
  float(7.8)
  [16]=>
  float(7.3)
  [17]=>
  float(7.1)
  [18]=>
  float(7)
  [19]=>
  float(6.8)
  [20]=>
  float(6.7)
  [21]=>
  float(6.5)
  [22]=>
  float(6.4)
  [23]=>
  float(6.2)
  [24]=>
  float(6.1)
  [25]=>
  float(5.9)
  [26]=>
  float(5.8)
  [27]=>
  float(5.6)
  [28]=>
  float(5.5)
  [29]=>
  float(5.3)
  [30]=>
  float(5.2)
  [31]=>
  int(5)
}

【问题讨论】:

    标签: javascript function math calculation


    【解决方案1】:

    这是一个使用 Python 和 numpy 进行计算的解决方案。尽管使用更多代码,但转换为 javascript 应该相当容易。最“复杂”的函数是np.linspace,它将一个范围划分为n 均匀分布的值:

    import numpy as np
    
    heightAvailable = 287
    maxSizeElement = 10
    minSizeElement = 5
    marginBottom = 2
    
    for n in range(2, 100):
        sizes = np.linspace(10, 5, n)  # n evenly distributed numbers between 10 and 5 (both included)
        total_space = np.sum(sizes) + (n - 1) * marginBottom
        print(f"With {n} rows; total_space: {total_space:.2f} mm")
        if total_space > heightAvailable:
            sizes = np.linspace(10, 5, n - 1)
            total_space = np.sum(sizes) + (n - 2) * marginBottom
            print(f"Use {n - 1} rows; total_space: {total_space:.1f} mm\nsizes:")
            print(sizes)
            break
    

    输出:

    With 2 rows; total_space: 17.00 mm
    With 3 rows; total_space: 26.50 mm
    With 4 rows; total_space: 36.00 mm
    ...
    With 28 rows; total_space: 264.00 mm
    With 29 rows; total_space: 273.50 mm
    With 30 rows; total_space: 283.00 mm
    With 31 rows; total_space: 292.50 mm
    Use 30 rows; total_space: 283.0 mm
    sizes:
    [10.          9.82758621  9.65517241  9.48275862  9.31034483  9.13793103
      8.96551724  8.79310345  8.62068966  8.44827586  8.27586207  8.10344828
      7.93103448  7.75862069  7.5862069   7.4137931   7.24137931  7.06896552
      6.89655172  6.72413793  6.55172414  6.37931034  6.20689655  6.03448276
      5.86206897  5.68965517  5.51724138  5.34482759  5.17241379  5.        ]
    

    对于更数学的方法,您可以用符号方式计算所有内容,例如使用 Python 的 sympy。请注意,小方块的各个尺寸是第一个和最后一个尺寸之间的插值。可以使用三角数公式“手动”计算公式并求解二次方程,或者让 sympy 完成工作:

    from sympy import symbols, Sum, Eq, solve
    
    heightAvailable, maxSizeElement, minSizeElement, marginBottom = symbols(
        'heightAvailable maxSizeElement minSizeElement marginBottom')
    
    i, n = symbols('i n')
    total = Sum((i - 1) / (n - 1) * maxSizeElement + (n - 1 - (i - 1)) / (n - 1) * minSizeElement,
                (i, 1, n)) + (n - 1) * marginBottom
    sol = solve(Eq(total.simplify(), heightAvailable), n)
    print(sol)
    print(sol[0].subs({heightAvailable: 287, maxSizeElement: 10, minSizeElement: 5, marginBottom: 2}).evalf())
    

    输出:

    [2*(heightAvailable + marginBottom)/(2*marginBottom + maxSizeElement + minSizeElement)]
    30.4210526315789
    

    【讨论】:

    • 是的,我考虑检查一下。但也给其他人一些时间来回答。
    • 对不起,我想我做到了。可能是我忘记了或网络问题。
    猜你喜欢
    • 1970-01-01
    • 2016-02-16
    • 2021-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-16
    • 1970-01-01
    相关资源
    最近更新 更多