# 一道数学题引发的惨案！4只小鸭子在一个圆形的大水池中，分别随机的出现圆圈中任意一点。4只鸭子在同一半圆内的概率是多少？

class Point {
private double x;
private double y;
//假设圆半径为1,圆心为原点
public Point() {
double a  = 0;double b  = 0;
do{
x = Math.random()*2-1;
y = Math.random()*2-1;
}while (outOfCircle(x,y));
}
@Override
public String toString() {
return "["+x+","+y+"]";
}
public Point(double x, double y) {
this.x = x;
this.y = y;
}
private boolean outOfCircle(double a, double b){ return a*a+b*b>1; }
public double getX() {
return x;
}
public double getY() {
return y;
}
}


class Line {
private double k;
private double b;
public Line(double k, double b) {
this.k = k;
this.b = b;
}
public double getK() {
return k;
}
public double getB() {
return b;
}
public double getXWhenY0() {
return -b / k;
}
public double getYWhenX0() {
return b;
}
}


public class Main {
public static void main(String[] args) {
int in = 0;
int count =10000000;
for (int i = 0; i < count; i++) {
Point[] ps =  build4Duck();
if (isOrNotInHalf(ps)) {
in += 1;
}
}
System.out.println("经过"+count+"实验，其中4只鸭子都在一侧的情况为"+in+"次");
System.out.println("概率为："+(double)in/count);
}

private static Point[] build4Duck(){
Point[] ps = new Point[4];
for(int i=0;i<ps.length;i++)
ps[i] = new Point();
return ps;
}

private static boolean isOrNotInHalf(Point[] ps) {
for(int i = 0;i<ps.length;i++){//跟距一个点坐标和圆心将圆分成两半
Line line = getLine(new Point(0,0),ps[i]);
if(line==null)return false;
boolean isInHalf = true;
//找到其余的第一个点是在直线上方还是下方
int ano = (i==0)?1:0;
boolean onOrDown = ps[ano].getY()-line.getK()*ps[ano].getX()>0;//斜率b是否大于0
for(int j  = ano+1;j<ps.length;j++){
if(i==j)continue;
isInHalf = isInHalf
&&(onOrDown==(ps[j].getY()-line.getK()*ps[j].getX()>0));//其余各点是否ano位置相同
}
if(isInHalf)return true;
}
return false;
}

private static Line getLine(Point one, Point ano) {
double x1 = one.getX();
double y1 = one.getY();
double x2 = ano.getX();
double y2 = ano.getY();
//斜率y = kx + b
double k = ((double) (y2 - y1)) / (x2 - x1);
if (k == 0) return null;
double b = y1 - k * x1;
return new Line(k, b);
}
}


10-02 114
09-30 564

09-24 3776
12-21 523
08-27 1386
02-07 1万+