如何找到两个值之间的分布



假设我有一个210mm x 297mm (A4)的页面。它的印刷边距是5毫米左右。我想打印1cm × 1cm的正方形来填充页面。每个正方形都有一个特定的边缘,比如右边1mm,下面2mm。现在计算我能得到多少平方很简单:

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

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

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


现在我想让第一行正方形是1cm × 1cm,最后一行是5mm × 5mm。

但是中间的所有行都应该用<1cm到>5毫米。从上到下逐渐减小

我如何找到行数和每一行的平方大小?


我能想出的最好的,但需要尝试与步骤:

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)
}

下面是使用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} mmnsizes:")
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

相关内容

  • 没有找到相关文章

最新更新