笔记-几何法解决三点定圆问题

Problem

bzoj1336/1337双倍经验题

题意概要:给定平面上\(n\)个点,求覆盖所有点的最小圆

Solution

刚看到这道题很迷,感觉感觉要\(O(n^3)\),但看了wwt的讲解,发现这题可以做到期望\(O(n)\),题解就不写了,网上到处都是(这篇比较明晰)

这里主要讲一下如何根据三点求过这三点的圆的问题

网上好像都是在解方程?

dalao代码:

if(fabs(a[j].y-a[i].y)<=eps||fabs(a[k].y-a[i].y)<=eps) continue;
l1.k=-(a[j].x-a[i].x)/(a[j].y-a[i].y); 
l1.b=(a[i].y+a[j].y)/2-l1.k*(a[i].x+a[j].x)/2;
l2.k=-(a[k].x-a[i].x)/(a[k].y-a[i].y);
l2.b=(a[i].y+a[k].y)/2-l2.k*(a[i].x+a[k].x)/2;
if(fabs(l1.k-l2.k)<=eps) continue;
o=intersection(l1,l2);r=o.dis(a[i]);

我用的向量+几何方法,而这种做法的核心代码很短 其实也没短到哪里去

pnt b1=(p0+p1)*0.5,b2=(p0+p2)*0.5,d1=p1-p0,d2=p2-p0;
d1.rev(),d2.rev();
return b1+d1*(((b1-b2)*d2)/(d2*d1));

但不用特判斜率啊,下面证明一下(下面的线段长度就直接写线段名啦)

先画一个三角形\(\triangle ABC\),简化一下,以\(A\)为原点,画两个向量\(\vec {AB},\vec{AC}\)(图一)

然后由于\(\triangle ABC\)的外接圆圆心在三角形三条中垂线交点处,所以我们取得\(AB,AC\)中点\(D,E\)(图二)

再做出中垂线\(DF,EG\),注意我们不会直接做出中垂线,但我们会旋转向量,设\(A\)为旋转中心,将\(AB\)旋转\(90°\)\(AH\),同理\(AC\)\(AI\),这个我们是可以用三角函数旋转出来的,但由于这个角是直角,所以可以特别判断,向量\((x,y)\)变为\((-y,x)\)

我们发现这时\(\vec{DF}\)\(\vec{EG}\)的交点就是我们要求的圆心坐标,不妨设为\(O\),我们这会儿需要得到\(O\)的坐标,即向量\(\vec {AO}\),考虑到\(\vec {AO}=\vec {AE}+\vec {EO}\),而我们已经知道\(\vec {AE}=\frac 12 \vec {AC}\),所以我们只用求\(\vec {EO}\)

再考虑到我们已知条件中仅有\(\vec {AI}=\vec {EG}\)是与之相关的,即\(EO=k\cdot \vec {EG}=k\cdot \vec {AI}\),我们要求出这个比值\(k\)

我们连接\(EF,DE,HI\),再过\(I\)\(IJ \perp AB\),过\(E\)\(EK \perp DF\)

这时做出了两个三角形\(\triangle AHI,\triangle EFD\)\(S_{\triangle AHI}=\frac 12AH\cdot AJ,S_{\triangle EFD}=\frac 12DF\cdot EK\),因为\(AH=ED\),所以\(\frac {EK}{AJ}=\frac{S_{\triangle AHI}}{S_{\triangle EFD}}\)

根据多年初中数学直觉,发现\(\triangle EKO∽ \triangle AJI\),理由是三条边分别平行,则三个角对应相等,根据上面的那个等式 ,发现\(k=\frac {EO}{AI}=\frac {EK}{AJ}=\frac{S_{\triangle AHI}}{S_{\triangle EFD}}\),而\(S_{\triangle AHI}=\frac 12 \vec{AH}×\vec{AI},S_{\triangle EFD}=\frac 12 \vec{DE}×\vec{DF}=\frac 12 (\vec{AE}-\vec{AD})×\vec{AH}\)

\(\vec {AO}\\=\vec {AE}+\vec {EO}\\=\vec {AE}+k\cdot \vec {AI}\\=\frac {EO}{AI}\cdot \vec {AI}\\=\frac {EK}{AJ}\cdot \vec {AI}\\=\frac{S_{\triangle AHI}}{S_{\triangle EFD}}\cdot \vec {AI}\\=\frac{\vec{AH}×\vec{AI}}{ (\vec{AE}-\vec{AD})×\vec{AH}}\cdot \vec {AI}\)

到此,以上\(\vec {AH},\vec {AI},\vec {AE},\vec {AD}\)都是已知量,\(\vec {AE},\vec {AD}\)为原来三角形中向量的一半,\(\vec {AH} , \vec {AI}\)为旋转后的向量

由此可知,我们只需要将两个向量旋转\(90°\),求两个叉积就可以根据给定的三个点求过这三个点的圆心

猜你喜欢

转载自www.cnblogs.com/penth/p/9335175.html
今日推荐