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


    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));
    

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

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

    然后由于( riangle 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=kcdot vec {EG}=kcdot vec {AI}),要求出这个比值(k)

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

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

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

    (vec {AO}\=vec {AE}+vec {EO}\=vec {AE}+kcdot vec {AI}\=frac {EO}{AI}cdot vec {AI}\=frac {EK}{AJ}cdot vec {AI}\=frac{S_{ riangle AHI}}{S_{ riangle 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°),求两个叉积就可以根据给定的三个点求过这三个点的圆心

    upd:现在回看这个做法感觉有些智障

  • 相关阅读:
    Servlet项目 创建方法
    1. 连接数据库
    Jsp application对象(全局变量)
    Jsp session属性、方法
    让python 3支持mysqldb的解决方法
    Python读写文件(进阶)
    python操作MongoDB
    使用Python Pandas处理亿级数据
    SurfingTheInternet
    matplotlib中日期显示(不显示为科学计数法)
  • 原文地址:https://www.cnblogs.com/penth/p/9335175.html
Copyright © 2020-2023  润新知