Coffee should be as black as hell, as strong as death, and as sweet as love
毫无疑问,这句话指的是 Espresso。嗯,我不是说苹果机上的 Web 套件,而是 30 cc 的浓缩咖啡。今天,我喝多了……
新的磨,新的杯子,当然要多喝几杯,但到底喝了多少,我决定计算一下。
杯子口直径57毫米,杯底直径31毫米,深度56毫米(依靠十年前机械功底目测)
计算体积?小意思,但如果不想用圆周率该怎么办?用随机数模拟咯。Ok,We do both.
1: dT = 57
2: dB = 31
3: h = 56
4:
5: //area of a circle
6: area = { r -> r ** 2 * Math.PI }
7:
8: //volumn of a cone
9: vCone = { d, h -> area(d / 2) * h / 3 }
10:
11: //volumn of a CUP, in mL
12: vCup = {
13: (vCone(dT, h + dB * h / (dT - dB)) - vCone(dB, dB * h / (dT - dB))) / 1000
14: }
15: println vCup()
16:
17: /* NO MORE PI */
18: random = { range -> Math.random() * range }
19: diameterAt = { height -> dB + (dT - dB) * height / h }
20:
21: // Some Pythagorean...
22: distanceSqr = { a1, b1, a2, b2 -> (a1 - a2) ** 2 + (b1 - b2) ** 2 }
23:
24: isInCup = { x, y, z -> (diameterAt(y) / 2) ** 2 > distanceSqr(x, z, dT / 2, dT / 2) }
25:
26: total = 1000000
27: trueTimes = 0
28:
29: total.times { if(isInCup(random(dT), random(h), random(dT))) trueTimes ++ }
30: vol = dT * dT * h * (trueTimes / total) / 1000 //mL
31: println vol
以上代码中vCup应用了圆椎体的计算公式;而之后的方法则通过随机产生一个点并判断其是否在杯子里的蒙特卡洛法统计出杯子的体积。
结论:87mL,唉,无良JS告诉我是75mL来着。容积的误导直接影响出ESP的质量啊……
PS. 在这一次的计算中,显然用圆周率要来的简单快速得多,那是因为形状很规则,如果要求一个不规则形状的体积,用蒙特卡罗法求就简单了,因为你需要的可能只是一个激光扫描图而不是超纠结的数学公式。
PS II. 如果牛顿和莱布尼茨有够快的随机数发生器,今天可能根本就没有微积分(也就不会有操着闽南语的老头在课堂上讲神马“把昏子和昏母昏别求导是种灰常重要的荒滑”了。
PS III. 现在,不需要任何额外的数学知识就可以计算多维空间里形状的体积了,简单的和数数一样。