题意:给定A,B,C,D,四个点和系数K1,K2,集合X中的点满足|A-X|>=K1|B-X|,集合Y中的点满足|C-Y|>=K2|D-Y|,求集合Z=X∩Y的大小
大学狗先梦回高中求下几何:
我们现在二维平面下求下形状
先从网上盗了个图,将就看下一:
前提条件
PA/PB=K
PM为∠APB的角平分线,有角平分线定理可得PA/PB=AM/MB
PN为∠APB外角的角平分线,我们过B点做一条直线PM平行线交AP于E,使得BE//PN
证明:
∵PN//BE,PM为∠APB外角的角平分线
∴∠MPB=∠PBE,∠PEB=∠MPE
∴PE=PB
∵PE/PA=NB/NA,PE=PB
∴PB/PA=NB/NA=MB/MA=1/K
∵PM,PN为角平分线
∴∠MPN为直角
∴P的轨迹为圆
我们上面得到了PB/PA=NB/NA=MB/MA=1/K,且P的运动轨迹为一个圆,现在可以来确定圆的圆心和半径大小了
假定A(Xa,Ya),B(Xb,Yb),设P(x,y),带入|AP|=K|BP|,解出圆心为(
k
∗
k
∗
x
2
−
x
1
k
∗
k
−
1
k*k*x2-x1 \over k*k-1
k∗k−1k∗k∗x2−x1,
k
∗
k
∗
y
2
−
y
1
k
∗
k
−
1
k*k*y2-y1 \over k*k-1
k∗k−1k∗k∗y2−y1),r=
k
∣
a
b
∣
k
∗
k
−
1
k|ab| \over k*k-1
k∗k−1k∣ab∣
题目是:|A-X|>=K1|B-X|,所以这题不是二维的圆,而是三维的球,圆心为(
k
∗
k
∗
x
2
−
x
1
k
∗
k
−
1
k*k*x2-x1 \over k*k-1
k∗k−1k∗k∗x2−x1,
k
∗
k
∗
y
2
−
y
1
k
∗
k
−
1
k*k*y2-y1 \over k*k-1
k∗k−1k∗k∗y2−y1,
k
∗
k
∗
z
2
−
z
1
k
∗
k
−
1
k*k*z2-z1 \over k*k-1
k∗k−1k∗k∗z2−z1),r=
k
∣
a
b
∣
k
∗
k
−
1
k|ab| \over k*k-1
k∗k−1k∣ab∣
相交后的体积有三种情况:
①两球不相交,结果为0
②两球是包含关系,结果为被包含的球的体积
③两球部分相交
球缺的体积公式:π H 2 H^{2} H2(R- H 3 H \over 3 3H),详情见:这里
现在来求下第三种情况:
即较大的球的半径为R,球心为A,另一个为半径为r,球心为B,两球相交形成的圆的半径为d,D为圆上一点,则可以得到
cos
\cos
cos∠BAD=
R
2
R^{2}
R2+
∣
A
B
∣
2
|AB|^{2}
∣AB∣2-
r
2
r^{2}
r2 / 2R|AB|,则h1=R*(1-
cos
\cos
cos∠BAD),同理可得h2
AcCode
#include<algorithm>
#include<iostream>
#include<cmath>
using namespace std;
class point {
public:
point(double x, double y, double z) { this->x = x, this->y = y, this->z = z; };
double getX() { return this->x; };
double getY() { return this->y; }
double getZ() { return this->z; }
private:
double x;
double y;
double z;
};
double getDis(point a, point b) {
double ans = sqrt(pow(a.getX() - b.getX(), 2) + pow(a.getY() - b.getY(), 2) + pow(a.getZ() - b.getZ(), 2));
return ans;
}
point getPoint(point A, point B, double k, double k1) {
double x1, y1, z1;
x1 = (1.0 * k1 * k1 * B.getX() - A.getX()) / k;
y1 = (1.0 * k1 * k1 * B.getY() - A.getY()) / k;
z1 = (1.0 * k1 * k1 * B.getZ() - A.getZ()) / k;
point ret(x1, y1, z1);
return ret;
}
signed main() {
int t;
double pi = acos(-1);
cin >> t;
while (t--) {
double x, y, z, k1, k2;
cin >> x >> y >> z;
point A(x, y, z);
cin >> x >> y >> z;
point B(x, y, z);
cin >> x >> y >> z;
point C(x, y, z);
cin >> x >> y >> z;
point D(x, y, z);
cin >> k1 >> k2;
double kk1 = k1 * k1 - 1;
double kk2 = k2 * k2 - 1;
double AB = getDis(A, B);
double CD = getDis(C, D);
double R1 = k1 * AB / abs(kk1);
double R2 = k2 * CD / abs(kk2);
point O1 = getPoint(A, B, kk1, k1);
point O2 = getPoint(C, D, kk2, k2);
double R = getDis(O1, O2);
if (R >= (R1 + R2)) {
cout << 0 << endl;
}
else if (R < abs(R1 - R2)) {
double ans1 = 4.0 * pi * R1 * R1 * R1 / 3;
double ans2 = 4.0 * pi * R2 * R2 * R2 / 3;
cout << min(ans1, ans2) << endl;
}
else {
double c1 = 1.0 * (R * R + R1 * R1 - R2 * R2) / (2 * R1 * R);
double c2 = 1.0 * (R * R + R2 * R2 - R1 * R1) / (2 * R2 * R);
double h1 = R1 * (1.0 - c1);
double h2 = R2 * (1.0 - c2);
double ans1 = pi * h1 * h1 * (R1 - h1 / 3);
double ans2 = pi * h2 * h2 * (R2 - h2 / 3);
cout << ans1 + ans2 << endl;
}
}
}