zoukankan      html  css  js  c++  java
  • 半平面交

    5.1  半平面交模板(from UESTC) 
     
    const double eps = 1e-8; 
    const double PI = acos(-1.0); 
    int sgn(double x) 
    { 
      if(fabs(x) < eps) return 0; 
      if(x < 0) return -1; 
      else return 1; 
    } 
    struct Point 
    { 
      double x,y; 
      Point(){} 
      Point(double _x,double _y) 
      { 
        x = _x; y = _y; 
      } 
      Point operator -(const Point &b)const 
      { 
        return Point(x - b.x, y - b.y); 
      } 
      double operator ^(const Point &b)const 
      { 
        return x*b.y - y*b.x; 
      } 
      double operator *(const Point &b)const 
      { 
        return x*b.x + y*b.y; 
      } 
    }; 
    struct Line 
    { 
      Point s,e; 
      double k; 
      Line(){} 
      Line(Point _s,Point _e) 
      { 
        s = _s; e = _e; 
        k = atan2(e.y - s.y,e.x - s.x); 
      } 
      Point operator &(const Line &b)const 
      { 
        Point res = s; 
        double t = ((s - b.s)^(b.s - b.e))/((s - e)^(b.s - b.e)); 
        res.x += (e.x - s.x)*t; 
        res.y += (e.y - s.y)*t; 
        return res; 
      } 
    }; 
    //半平面交,直线的左边代表有效区域 
    bool HPIcmp(Line a,Line b) 
    { 
      if(fabs(a.k - b.k) > eps)return a.k < b.k; 
      return ((a.s - b.s)^(b.e - b.s)) < 0; 
    } 
    Line Q[110]; 
    void HPI(Line line[], int n, Point res[], int &resn) 
    { 
      int tot = n; 
      sort(line,line+n,HPIcmp); 
      tot = 1; 
      for(int i = 1;i < n;i++) 
        if(fabs(line[i].k - line[i-1].k) > eps)
          line[tot++] = line[i]; 
      int head = 0, tail = 1; 
      Q[0] = line[0]; 
      Q[1] = line[1]; 
      resn = 0; 
      for(int i = 2; i < tot; i++) 
      { 
        if(fabs((Q[tail].e-Q[tail].s)^(Q[tail-1].e-Q[tail-1].s)) < eps || 
    fabs((Q[head].e-Q[head].s)^(Q[head+1].e-Q[head+1].s)) < eps) 
          return; 
        while(head < tail && (((Q[tail]&Q[tail-1]) - 
    line[i].s)^(line[i].e-line[i].s)) > eps) 
          tail--; 
        while(head < tail && (((Q[head]&Q[head+1]) - 
    line[i].s)^(line[i].e-line[i].s)) > eps) 
          head++; 
        Q[++tail] = line[i]; 
      } 
      while(head < tail && (((Q[tail]&Q[tail-1]) - 
    Q[head].s)^(Q[head].e-Q[head].s)) > eps) 
        tail--; 
      while(head < tail && (((Q[head]&Q[head-1]) - 
    Q[tail].s)^(Q[tail].e-Q[tail].e)) > eps) 
        head++; 
      if(tail <= head + 1)return; 
      for(int i = head; i < tail; i++) 
        res[resn++] = Q[i]&Q[i+1]; 
      if(head < tail - 1) 
        res[resn++] = Q[head]&Q[tail]; 
    } 
    5.2  普通半平面交写法 
    POJ 1750 
    const double eps = 1e-18; 
    int sgn(double x) 
    { 
      if(fabs(x) < eps)return 0; 
      if(x < 0)return -1; 
      else return 1; 
    } 
    struct Point 
    { 
      double x,y; 
      Point(){} 
      Point(double _x,double _y) 
      { 
        x = _x; y = _y; 
      } 
      Point operator -(const Point &b)const 
      { 
        return Point(x - b.x, y - b.y); 
      } 
      double operator ^(const Point &b)const 
      { 
        return x*b.y - y*b.x; 
      } 
      double operator *(const Point &b)const 
      { 
        return x*b.x + y*b.y; 
      } 
    }; 
    //计算多边形面积 
    double CalcArea(Point p[],int n) 
    { 
      double res = 0; 
      for(int i = 0;i < n;i++) 
        res += (p[i]^p[(i+1)%n]); 
      return fabs(res/2); 
    } 
    //通过两点,确定直线方程 
    void Get_equation(Point p1,Point p2,double &a,double &b,double &c) 
    { 
      a = p2.y - p1.y; 
      b = p1.x - p2.x; 
      c = p2.x*p1.y - p1.x*p2.y; 
    } 
    //求交点 
    Point Intersection(Point p1,Point p2,double a,double b,double c) 
    { 
      double u = fabs(a*p1.x + b*p1.y + c); 
      double v = fabs(a*p2.x + b*p2.y + c); 
      Point t; 
      t.x = (p1.x*v + p2.x*u)/(u+v); 
      t.y = (p1.y*v + p2.y*u)/(u+v); 
      return t; 
    } 
    Point tp[110]; 
    void Cut(double a,double b,double c,Point p[],int &cnt) 
    { 
      int tmp = 0; 
      for(int i = 1;i <= cnt;i++) 
      { 
        //当前点在左侧,逆时针的点 
        if(a*p[i].x + b*p[i].y + c < eps)tp[++tmp] = p[i]; 
        else 
        { 
          if(a*p[i-1].x + b*p[i-1].y + c < -eps) 
            tp[++tmp] = Intersection(p[i-1],p[i],a,b,c); 
          if(a*p[i+1].x + b*p[i+1].y + c < -eps) 
            tp[++tmp] = Intersection(p[i],p[i+1],a,b,c); 
        } 
      } 
      for(int i = 1;i <= tmp;i++) 
        p[i] = tp[i]; 
      p[0] = p[tmp]; 
      p[tmp+1] = p[1]; 
      cnt = tmp; 
    } 
    double V[110],U[110],W[110]; 
    int n; 
    const double INF = 100000000000.0; 
    Point p[110]; 
    bool solve(int id) 
    { 
      p[1] = Point(0,0); 
      p[2] = Point(INF,0); 
      p[3] = Point(INF,INF); 
      p[4] = Point(0,INF); 
      p[0] = p[4]; 
      p[5] = p[1]; 
      int cnt = 4; 
      for(int i = 0;i < n;i++) 
        if(i != id) 
        { 
          double a = (V[i] - V[id])/(V[i]*V[id]); 
          double b = (U[i] - U[id])/(U[i]*U[id]); 
          double c = (W[i] - W[id])/(W[i]*W[id]); 
          if(sgn(a) == 0 && sgn(b) == 0) 
          { 
            if(sgn(c) >= 0)return false; 
            else continue; 
          } 
          Cut(a,b,c,p,cnt); 
        } 
      if(sgn(CalcArea(p,cnt)) == 0)return false; 
      else return true; 
    } 
    int main() 
    { 
        while(scanf("%d",&n) == 1) 
      { 
        for(int i = 0;i < n;i++) 
          scanf("%lf%lf%lf",&V[i],&U[i],&W[i]); 
        for(int i = 0;i < n;i++) 
        { 
          if(solve(i))printf("Yes
    "); 
          else printf("No
    "); 
        } 
      } 
        return 0; 
    } 
    

      

  • 相关阅读:
    RDIFramework.NET V3.3 WinForm版新增日程管理功能模块
    RDIFramework.NET V3.3 WinForm版角色授权管理新增角色对操作权限项、模块起止生效日期的设置
    RDIFramework.NET V3.3 Web版角色授权管理新增角色对操作权限项、模块起止生效日期的设置
    前端神器-神级代码编辑软件Sublime Text下载、使用教程、插件推荐说明、全套快捷键
    C# net request payload形式发送post请求
    RDIFramework.NET ━ .NET快速信息化系统开发框架 V3.2版本正式发布
    RDIFramework.NET ━ .NET快速信息化系统开发框架 V3.2->WinForm版本重构岗位授权管理界面更规范、高效与美观
    NET快速信息化系统开发框架 V3.2 ->WinForm部分全部重构为Dev风格界面
    NET快速信息化系统开发框架 V3.2 -> “用户管理”主界面使用多表头展示、增加打印功能
    SQLServer特殊字符/生僻字与varchar
  • 原文地址:https://www.cnblogs.com/xzxl/p/7247665.html
Copyright © 2011-2022 走看看