ZOJ 1081 Within(点是否在多边形内)| 计算几何

ZOJ 1081 Within

我使用的是“射线法”:从该点出发,作一条向左的水平射线,与多边形的边的交点有奇数个则点在多边形内。

需要注意的点:

  1. 如果点在多边形的边上特判。
  2. 考虑射线与多边形的一个交点是多边形的顶点的情况,

    最左边的那个顶点算一个交点,左边第二种的那个顶点算两个交点或不算交点都行(但不能算一个交点)。
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
typedef long long ll;
template <class T>
void read(T &x){
    char c;
    bool op = 0;
    while(c = getchar(), c < '0' || c > '9')
    if(c == '-') op = 1;
    x = c - '0';
    while(c = getchar(), c >= '0' && c <= '9')
    x = x * 10 + c - '0';
    if(op) x = -x;
}
template <class T>
void write(T x){
    if(x < 0) putchar('-'), x = -x;
    if(x >= 10) write(x / 10);
    putchar('0' + x % 10);
}
const int N = 105;
int n, m;
struct point {
    int x, y;
    point(){}
    point(int _x, int _y): x(_x), y(_y){}
    point operator - (point b){
    return point(x - b.x, y - b.y);
    }
    int operator * (point b){ // 这是叉乘
    return x * b.y - y * b.x;
    }
    int operator % (point b){ // 这是点乘
    return x * b.x + y * b.y;
    }
};
bool bel(point p, point u, point v){
    if((u - p) * (v - p)) return 0;
    return (u - p) % (v - p) <= 0;
}
struct poly {
    point p[N];
    bool includ(point q){
    int cnt = 0;
    for(int i = 1; i <= n; i++){
        if(bel(q, p[i], p[i + 1])) return 1;
        int d1 = q.y - p[i].y, d2 = q.y - p[i + 1].y;
        int det = (p[i] - q) * (p[i + 1] - q);
        if((det >= 0 && d1 < 0 && d2 >= 0) ||
           (det <= 0 && d2 < 0 && d1 >= 0)) cnt++;
    }
    return cnt & 1;
    }
} P;
int main(){
    int T = 0, u, v;
    while(read(n), n){
    if(T) puts("");
    printf("Problem %d:\n", ++T);
    read(m), read(u), read(v);
    P.p[1] = P.p[n + 1] = (point){u, v};
    for(int i = 2; i <= n; i++){
        read(u), read(v);
        P.p[i] = (point){u, v};
    }
    while(m--){
        read(u), read(v);
        if(P.includ((point){u, v})) puts("Within");
        else puts("Outside");
    }
    }
    return 0;
}
时间: 2024-10-05 20:58:01

ZOJ 1081 Within(点是否在多边形内)| 计算几何的相关文章

zoj 1081 Points Within 判断点是否在任意多边形内(模板)

题目来源: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=81 分析: 从p点出发做平行于x轴的射线 l. 求射线与 多边形 线段的交点数num, 若是偶数 , 该点 在外, 若为奇数, 该点在内. 注意: 两个特判, 1:   一个是 射线 l 与 多边形的边  重合 , 若该p点在 线段上, 返回1, 否则 交点 记为 0 个 2: 一个是 射线与 线段的交点 ,为线段的端点, 则我们 对线段的 较低交点 不计算. 代码

ZOJ 1081 Points Within | 判断点在多边形内

题目: 给个n个点的多边形,n个点按顺序给出,给个点m,判断m在不在多边形内部 题解: 网上有两种方法,这里写一种:射线法 大体的思想是:以这个点为端点,做一条平行与x轴的射线(代码中射线指向x轴正方向) 如果交点个数为奇数的话就在内部,如果为偶数(包括0)就在外部 #include<cstdio> #include<algorithm> #include<cstring> #define N 105 using namespace std; int n,m; stru

ZOJ 3720 Magnet Darts (计算几何,概率,判点是否在多边形内)

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3720 题意: 在一个矩形区域投掷飞镖,因此飞镖只会落在整点上,投到每个点的得分是Ax+By.矩形区域里面有个多边形,如果飞镖投在多边形里面则得分,求最终的得分期望. 即:给定一个矩形内的所有整数点,判断这些点是否在一个多边形内 方法: 计算几何的判点是否在多边形内(几何模板),如果在,则令得分加(Ax+By)*以此点为中心边长为1的正方形面积 1 void solve()

点在多边形内的判断

在看zrender源码时,看到点在多边形内的判断代码,特意粘出来,参考下: /** * 多边形包含判断 * 采用 non-zero winding rule */ function isInsidePolygon(points, x, y) { var N = points.length; var w = 0; for (var i = 0, j = N - 1; i < N; i++) { var x0 = points[j][0]; var y0 = points[j][1]; var x1

A Round Peg in a Ground Hole - POJ 1584 (判断凸多边形&amp;判断点在多边形内&amp;判断圆在多边形内)

题目大意:首先给一个圆的半径和圆心,然后给一个多边形的所有点(多边形按照顺时针或者逆时针给的),求,这个多边形是否是凸多边形,如果是凸多边形在判断这个圆是否在这个凸多边形内. 分析:判断凸多边形可以使用相邻的三个点叉积判断,因为不知道顺时针还是逆时针,所以叉积如果有有整数和负数,那么一定不是凸多边形(注意允许多多点在一条线段上).判断圆在凸多边形首先要判断圆心是否在多边形内,如果在多边形内,再次判断圆心到达到变形每条边的最短距离,如果小于半径就是不合法.ps:一道好题,通过这个题学会了不少东西.

判断点是否在多边形内

有一个n边形,顶点为p1,p2,...,pn;给定一个已知点p,判断p在此多边形内还是外. 预备知识: 两线段相交的定义,如果一条线段的两端分别处在另一条线段的两端,则此两线段相交 判断2点在线段的两侧可以用向量的叉乘实现! 基本步骤: 1,过p点垂直向上作一条射线 2,判断此射线与n边形n条边的交点 3,把所有交点相加,如果是奇数则说明在多边形内,否则在多边形外 思路非常的简单,另外说明一下几种特殊的情况: 1,射线与多边形的顶点相交:比如射线过多边形的Pi点,则如果Pi-1和Pi+1在此射线

如何判断一个点是否在一个多边形内?

提示:对多边形进行分割,成为一个个三角形,判断点是否在三角形内. 一个非常有用的解析几何结论:如果P2(x1,y1),P2(x2,y2), P3(x3,y3)是平面上的3个点,那么三角形P1P2P3的面积等于下面绝对值的二分之一: | x1  y1  1 | | x2 y2  1 | = x1y2 + x3y1 + x2y3 –x3y2 – x2y1 – x1y3 | x3 y3  1 | 当且仅当点P3位于直线P1P2(有向直线P1->P2)的右侧时,该表达式的符号为正.这个公式可以在固定的时

经纬度计算是否在圆形内,是否在矩形内,是否在多边形内方法

class 点面关系{static void Main(string[] args){//Vector2D point1 = new Vector2D(39.909209536859834, 116.3225715637207);//inVector2D point1 = new Vector2D(39.901045, 116.415596);//outVector2D cPoint = new Vector2D(39.909209536859834, 116.3225715637207); C

poj 1265 Area 面积+多边形内点数

Area Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 5861   Accepted: 2612 Description Being well known for its highly innovative products, Merck would definitely be a good target for industrial espionage. To protect its brand-new resear