计算几何模板 ——求多边形有多少条对称轴

#include <cstdio>

#include <cmath>

#include <set>

#include <algorithm>

using namespace std;

const double eps=1e-8;

const double pi=3.141592653589793;

inline int cmp(double x)

{

    if (fabs(x)<eps) return 0;

    return x>0?1:-1;

}

int i,j,m,n,k,ans;

struct point

{

    double x,y;

    point () {}

    point (double _x,double _y):x(_x),y(_y) {}

    friend point operator + (point a,point b)

    {

        return point(a.x+b.x,a.y+b.y);

    }

    friend point operator - (point a,point b)

    {

        return point(a.x-b.x,a.y-b.y);

    }

    friend point operator * (point a,double d)

    {

        return point(a.x*d,a.y*d);

    }

    friend point operator / (point a,double d)

    {

        return point(a.x/d,a.y/d);

    }

    friend bool operator == (point a,point b)

    {

        return cmp(a.x-b.x)==0 && cmp(a.y-b.y)==0;

    }

    friend bool operator != (point a,point b)

    {

        return cmp(a.x-b.x)!=0 || cmp(a.y-b.y)!=0;

    }

    friend bool operator < (point a,point b)

    {

        return a.x<b.x||(a.x==b.x&&a.y<b.y);

    }

};

set <point> s;point p[1005];

inline bool isint(double x)

{

    return fabs(x-(int)(x+0.5))<eps;

}

inline double dis(point a,point b)

{

    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));

}

inline double dis_(point a,point b)

{

    return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);

}

inline double det(point a,point b,point c)//向量ca×向量cb

{

    return (a.x-c.x)*(b.y-c.y)-(b.x-c.x)*(a.y-c.y);

}



inline int parallel(point u1,point u2,point v1,point v2)

{

 return fabs((u1.x-u2.x)*(v1.y-v2.y)-(v1.x-v2.x)*(u1.y-u2.y))<eps;

}



/*inline point intersection(point u1,point u2,point v1,point v2)

{

 point ret=u1;

 double t=((u1.x-v1.x)*(v1.y-v2.y)-(u1.y-v1.y)*(v1.x-v2.x))/((u1.x-u2.x)*(v1.y-v2.y)-(u1.y-u2.y)*(v1.x-v2.x));

 ret.x+=(u2.x-u1.x)*t;

 ret.y+=(u2.y-u1.y)*t;

 return ret;

}*/

inline double cross(point a,point b,point c)//向量ab×向量ac

{

    return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y);

}

inline point intersection(point a,point b,point c,point d)

{

     double u=cross(a,b,c), v=cross(b,a,d);

     return point((c.x*v+d.x*u)/(u+v),(c.y*v+d.y*u)/(u+v));

}

inline point rotation(point a,double angle)

{

   double tx,ty;

   tx=cos(angle)*100;

   ty=sin(angle)*100;

   return point(a.x+tx,a.y+ty);

}

inline double getk(point a,point b)

{

    return atan2(a.y-b.y,a.x-b.x);

}

point point_op(point x,point a,point b)

{

    if(a==b) return point(a.x+a.x-x.x,a.y+a.y-x.y);

    point pro=point(x.x+a.y-b.y,x.y+b.x-a.x);

    point o=intersection(a,b,x,pro);

    return o*2-x;

}

int judge(point a,point b)

{

    for (int i=1;i<=n;i++)

    {

    point tt=point_op(p[i],a,b);

    if (!s.count(tt)) return 0;

    }

    return 1;

}

point MAKE_point(point a,point b,point c)

{

    return point(c.x+a.y-b.y,c.y+b.x-a.x);

}

int main()

{

    point a,b,c,d,mid1,mid2,pro1,pro2,o;double angle,k1,k2,x,y;

    int T=0;

        while (scanf("%d",&n)==1&&n)

        {

        T++;

        s.clear();

        for (i=1;i<=n;i++)

        {

            scanf("%lf%lf",&p[i].x,&p[i].y);

            s.insert(p[i]);

        }

        ans=judge(p[1],p[2]);

        mid1=(p[1]+p[2])*0.5;

        pro1=MAKE_point(p[1],p[2],mid1);

        ans+=judge(mid1,pro1);

        for (i=3;i<=n;i++)

        {

            mid1=(p[1]+p[i])*0.5;mid2=(p[2]+p[i])*0.5;

            pro1=MAKE_point(p[1],p[i],mid1);

            pro2=MAKE_point(p[2],p[i],mid2);

            ans+=judge(mid1,pro1);

            ans+=judge(mid2,pro2)&&!cmp(cross(p[1],mid2,pro2));

        }

        printf("Polygon #%d has %d symmetry line(s).\n",T,ans);

        }

    return 0;

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值