[p5.js]求解四只鸭子在同一半圆池塘的概率,答案令人震惊!
求解四只鸭子在同一半圆池塘的概率,答案令人震惊!
之前老早就看过这个问题了。当时随便解了解,感觉概率是1/2,然后就过去了。
正好互动媒体老师要可视化概率论问题,我就做了这个。
老规矩,先说一下思路
思路:暴力测试
先是随机在圆内放四个点,然后判断这四个点是否在同一半圆,如果是的话就记录下来。如此循环。
然后最后的概率就是同一半圆的次数/测试总次数。
当然啦,这个答案肯定不是个精确值。但如果测试次数足够大的话,答案就无限逼近正确答案。
随机放点
这个模型最重要的部分就是随机放点!。
网上看了几种思路,都觉得不行。自己想了一个。
我觉得效果还行(非常完美)
大致思路是这样的,先是随机取点所在的弧度。这个毋庸置疑,非常随机(0,2PI);
然后取点所在的半径。大概想法就是微积分的方法。大概就是sqrt(点所在半径的面积/总面积)*圆的半径。
下面是代码。比较简单,就不说明了
//返回一个2维向量,x为点的弧度,y为点的半径
function randomPointOfCircle(r)
{
theta=random(0,TWO_PI);
circleArea=PI*r*r;
pointArea=random(0,circleArea);
randomR=sqrt(pointArea/circleArea)*r;
circlePoint= createVector(theta, randomR);
return circlePoint;
}
判断是否为同一半圆
这个就更简单了。大概就是看他们弧度之间的弧度差。如果最大的弧度差<PI,就证明不在同一圆内
//pointList点的弧度的list
function pointsInHalfCircle(pointList,num)
{
pointList=sort(pointList,num);
maxTheta=TWO_PI-(pointList[num-1]-pointList[0]);//第一个和最后一个
for(let i=0;i<num-1;i++)
{
maxTheta=max(maxTheta,pointList[i+1]-pointList[i]);
}
console.log(maxTheta);
if(maxTheta<PI)
{
return false;
}
return true;
}
注意!因为圆的的弧度是(0,2PI)。如果按照顺时针方向来算弧度差的话,那么最后一个和第一个之间的差,还要用2PI来减。
结果
我就测试了两千多次,如果测试次数更多的话,可能结果还会变异变。
鼠标滚轮:改变测试频率。
鼠标点击:暂停
有人吗,有人吱一声。送代码!