• poj1584 A round peg in a ground hole【计算几何】


    含【判断凸包】,【判断点在多边形内】,【判断圆在多边形内】模板 

     凸包:即凸多边形

    用不严谨的话来讲,给定二维平面上的点集,凸包就是将最外层的点连接起来构成的凸多边形,它能包含点集中所有的点。

    The DIY Furniture company specializes in assemble-it-yourself furniture kits. Typically, the pieces of wood are attached to one another using a wooden peg that fits into pre-cut holes in each piece to be attached. The pegs have a circular cross-section and so are intended to fit inside a round hole. 
    A recent factory run of computer desks were flawed when an automatic grinding machine was mis-programmed. The result is an irregularly shaped hole in one piece that, instead of the expected circular shape, is actually an irregular polygon. You need to figure out whether the desks need to be scrapped or if they can be salvaged by filling a part of the hole with a mixture of wood shavings and glue. 
    There are two concerns. First, if the hole contains any protrusions (i.e., if there exist any two interior points in the hole that, if connected by a line segment, that segment would cross one or more edges of the hole), then the filled-in-hole would not be structurally sound enough to support the peg under normal stress as the furniture is used. Second, assuming the hole is appropriately shaped, it must be big enough to allow insertion of the peg. Since the hole in this piece of wood must match up with a corresponding hole in other pieces, the precise location where the peg must fit is known. 
    Write a program to accept descriptions of pegs and polygonal holes and determine if the hole is ill-formed and, if not, whether the peg will fit at the desired location. Each hole is described as a polygon with vertices (x1, y1), (x2, y2), . . . , (xn, yn). The edges of the polygon are (xi, yi) to (x i+1, y i+1) for i = 1 . . . n − 1 and (xn, yn) to (x1, y1).

    Input

    Input consists of a series of piece descriptions. Each piece description consists of the following data: 
    Line 1 < nVertices > < pegRadius > < pegX > < pegY > 
    number of vertices in polygon, n (integer) 
    radius of peg (real) 
    X and Y position of peg (real) 
    n Lines < vertexX > < vertexY > 
    On a line for each vertex, listed in order, the X and Y position of vertex The end of input is indicated by a number of polygon vertices less than 3.

    Output

    For each piece description, print a single line containing the string: 
    HOLE IS ILL-FORMED if the hole contains protrusions 
    PEG WILL FIT if the hole contains no protrusions and the peg fits in the hole at the indicated position 
    PEG WILL NOT FIT if the hole contains no protrusions but the peg will not fit in the hole at the indicated position

    Sample Input

    5 1.5 1.5 2.0
    1.0 1.0
    2.0 2.0
    1.75 2.0
    1.0 3.0
    0.0 2.0
    5 1.5 1.5 2.0
    1.0 1.0
    2.0 2.0
    1.75 2.5
    1.0 3.0
    0.0 2.0
    1

    Sample Output

    HOLE IS ILL-FORMED
    PEG WILL NOT FIT

     题意:

    给定n个点 这n个点组成一个多边形

    给定一个peg的坐标和半径

    首先判断这个多边形是不是凸多边形 若不是 输出“HOLE IS ILL-FORMED”

    否则判断peg和多边形的关系 若peg所代表的圆在多边形内部输出“PEG WILL FIT”

    否则输出“PEG WILL NOT FIT”

    思路:

    首先将n个点构造成封闭图形,判断是不是一个凸包

      求连续两条边的叉乘,如果正负号与之前的出现了不同,说明不是凸包

    再判断圆心与多边形的关系

       设圆心为P,逐条枚举n边形的边AB,利用
      

         计算PA和PB的夹角,最后求和得到的就是环顾角。

      (1)       圆心在多边形内部时,环顾角=±360

      (2)       圆心在多边形外部时,环顾角=0

      (3)       圆心在多边形边上时(不包括顶点),环顾角=±180

      (4)       圆心在多边形顶点时,环顾角为(0,360)之间的任意角,其实就是圆心所在的顶点的两条邻接边的夹角。

    最后判断整个圆是否在多边形内部

      只需要求出圆心到边的最短距离 若大于半径则在多边形内

      设圆心为P,逐条枚举n边形的边AB,利用得到△PAB的面积,

      再根据公式S=0.5*|AB|*h,可以得到 

       枚举所有h与圆的半径R比对,只要所有的边都有h - R>=0,则说明圆在多边形内

      1 //#include <bits/stdc++.h>
      2 #include<iostream>
      3 #include<cmath>
      4 #include<algorithm>
      5 #include<stdio.h>
      6 
      7 using namespace std;
      8 typedef long long int LL;
      9 
     10 const double eps = 1e-6;
     11 const double pi = 3.141592654;
     12 int n;
     13 double radius;
     14 struct point{
     15     double x, y;
     16 }peg;
     17 
     18 int precision(double x)
     19 {
     20     if(fabs(x) <= eps){
     21         return 0;
     22     }
     23     return x > 0 ? 1: -1;
     24 }
     25 
     26 double dotdet(double x1, double y1, double x2, double y2)
     27 {
     28     return x1 * x2 + y1 * y2;
     29 }
     30 
     31 double det(double x1, double y1, double x2, double y2)
     32 {
     33     return x1 * y2 - x2 * y1;
     34 }
     35 
     36 double cross(point a, point b, point c, point d)
     37 {
     38     return det(b.x - a.x, b.y - a.y, d.x - c.x, d.y - c.y);
     39 }
     40 
     41 double distant(point a, point b)
     42 {
     43     return sqrt((b.x - a.x) * (b.x - a.x) + (b.y - a.y) * (b.y - a.y));
     44 }
     45 
     46 double angle(point a, point b, point p)
     47 {
     48     return acos(dotdet(a.x - p.x, a.y - p.y, b.x - p.x, b.y - p.y) / (distant(a, p) * distant(b, p)));
     49 }
     50 
     51 bool isconvex(point *vectex)
     52 {
     53     int direction = 0;
     54     //1, 逆时针;-1, 顺时针
     55     for(int i = 0; i < n; i++){
     56         int temp = precision(cross(vectex[i], vectex[i + 1], vectex[i + 1], vectex[i + 2]));
     57 
     58         if(!direction){
     59             direction = temp;
     60         }
     61         if(direction * temp < 0){
     62             return false;
     63         }
     64     }
     65     return true;
     66 }
     67 
     68 bool is_in(point *vectex)
     69 {
     70     double circleAngle = 0.0;
     71     for(int i = 1; i <= n; i++){
     72         if(precision(cross(peg, vectex[i], peg, vectex[i + 1])) >= 0){
     73             circleAngle += angle(vectex[i], vectex[i + 1], peg);
     74         }
     75         else{
     76             circleAngle -= angle(vectex[i], vectex[i + 1], peg);
     77         }
     78     }
     79 
     80     if(precision(circleAngle) == 0){
     81         return false;
     82         //peg在多边形外部
     83     }
     84     else if(precision(circleAngle - pi) == 0 || precision(circleAngle + pi) == 0){
     85         //peg在多边形边上
     86         if(precision(radius) == 0){
     87             return true;
     88         }
     89     }
     90     else if(precision(circleAngle - 2 * pi) == 0 || precision(circleAngle + 2 * pi) == 0){
     91         return true;
     92     }
     93     else{
     94         //peg在多边形顶点上
     95         if(precision(radius) == 0){
     96             return true;
     97         }
     98     }
     99     return false;
    100 }
    101 
    102 bool isfit(point *vectex)
    103 {
    104     for(int i = 0; i <= n; i++){
    105         int k = precision(fabs(cross(peg, vectex[i], peg, vectex[i + 1]) / distant(vectex[i], vectex[i + 1])) - radius);
    106         if(k < 0){
    107             return false;
    108         }
    109     }
    110     return true;
    111 }
    112 
    113 int main()
    114 {
    115     while(scanf("%d", &n) != EOF && n >= 3){
    116         cin>> radius >> peg.x >> peg.y;
    117         point *vectex = new point[n + 2];
    118 
    119         for(int i = 1; i <= n; i++){
    120             cin>>vectex[i].x >> vectex[i].y;
    121         }
    122 
    123         //构成封闭多边形
    124         vectex[0].x = vectex[n].x;
    125         vectex[0].y = vectex[n].y;
    126         vectex[n + 1].x = vectex[1].x;
    127         vectex[n + 1].y = vectex[1].y;
    128 
    129         if(!isconvex(vectex)){
    130             cout<<"HOLE IS ILL-FORMED"<<endl;
    131         }
    132         else{
    133             bool flag1 = is_in(vectex);
    134             bool flag2 = isfit(vectex);
    135 
    136             if(flag1 && flag2){
    137                 cout<<"PEG WILL FIT"<<endl;
    138             }
    139             else{
    140                 cout<<"PEG WILL NOT FIT"<<endl;
    141             }
    142         }
    143         delete vectex;
    144     }
    145     return 0;
    146 }
  • 相关阅读:
    R语言中log1p()函数
    linux中awk命令实现科学计数法和普通数值的相互转换
    linux中awk命令实现保留指定小数位数
    redhat8中使用nmtui命令图形界面配置网络IP
    redhat8基于vmware软件图形界面配置IP
    R语言中read.table函数中check.names = F参数的作用
    R语言中实现相同行名自动重命名
    redhat9中配置静态IP(nmtui命令)
    redhat8如何配置静态IP
    redhat8中配置yum仓库
  • 原文地址:https://www.cnblogs.com/wyboooo/p/9736459.html
Copyright © 2020-2023  润新知