[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来减。

结果

我就测试了两千多次,如果测试次数更多的话,可能结果还会变异变。

鼠标滚轮:改变测试频率。

鼠标点击:暂停

有人吗,有人吱一声。送代码!

posted @ 2020-12-13 19:33  小夏的魔仙堡  阅读(2710)  评论(0编辑  收藏  举报