码迷,mamicode.com
首页 > 其他好文 > 详细

最小圆覆盖(Smallest Enclosing Discs)

时间:2015-11-18 21:18:44      阅读:224      评论:0      收藏:0      [点我收藏+]

标签:

随机增量算法(a randomized incremental algorithm)

#define sqr(x) ((x)*(x))
#define EPS 1e-4

struct P{
    double x, y;
    P(double x, double y):x(x),y(y){}
    P(P &a, P &b):x(b.x-a.x),y(b.y-a.y){}
    P(){}
    P mid(P &a){
        return P((a.x+x)/2, (a.y+y)/2);
    }
    double cross(P &a){
        return x*a.y-y*a.x;
    }
    double len2(){
        return sqr(x)+sqr(y);
    }
    double dis(P &a){
        return sqrt(sqr(x-a.x)+sqr(y-a.y));
    }
    void print(){
        printf("%f %f\n", x, y);
    }
};

struct Disc{
    P o;
    double r;
    bool cover(P &a){
        return r-o.dis(a) >= -EPS;
    }
    Disc(){}
    Disc(P &o, double r):o(o),r(r){}
    Disc(P &a, P &b):o(a.mid(b)), r(a.dis(b)/2){}
    Disc(P &a, P &b, P &c){
        double t1=b.len2()-a.len2();
        double t2=c.len2()-a.len2();
        P p1(a, b), p2(a, c);
        double t3=p1.cross(p2)*2;
        P p3(t1, p1.y), p4(t2, p2.y);
        P p5(p1.x, t1), p6(p2.x, t2);
        o=P(p3.cross(p4)/t3, p5.cross(p6)/t3);
        r=o.dis(a);
    }
};

Disc MinDisc(vector<P> &p){
    if(p.size()<=1) return Disc();
    random_shuffle(p.begin(), p.end());
    Disc d(p[0], p[1]);
    for(int i=2; i<p.size(); i++)
        if(!d.cover(p[i])){
            d=Disc(p[0], p[i]);
            for(int j=1; j<i; j++)
                if(!d.cover(p[j])){
                    d=Disc(p[i], p[j]);
                    for(int k=0; k<j; k++)
                        if(!d.cover(p[k]))
                            d=Disc(p[i], p[j], p[k]);
                }
        }
    return d;
}

 

最小圆覆盖(Smallest Enclosing Discs)

标签:

原文地址:http://www.cnblogs.com/Patt/p/4975878.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!