POJ 1410 (线段是否与多边形相交 + 点是否在多边形内)

题目:传送门

题意:有 n 个测试样例,每个样例,输入四个点,前两个点代表一条线段,后两个点代表正方形的两个对角端点。

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <queue>
#include <map>
#include <vector>
#include <set>
#include <string>
#include <math.h>
#define LL long long
#define mem(i, j) memset(i, j, sizeof(i))
#define rep(i, j, k) for(int i = j; i <= k; i++)
#define dep(i, j, k) for(int i = k; i >= j; i--)
#define pb push_back
#define make make_pair
#define INF 1e20
#define inf LLONG_MAX
#define PI acos(-1)
using namespace std;

const int N = 1e2 + 5;
const double eps = 1e-10;

struct Point {
    double x, y;
    Point(double x = 0, double y = 0) : x(x), y(y) { } /// 构造函数
};

/// 向量加减乘除
inline Point operator + (const Point& A, const Point& B) { return Point(A.x + B.x, A.y + B.y); }
inline Point operator - (const Point& A, const Point& B) { return Point(A.x - B.x, A.y - B.y); }
inline Point operator * (const Point& A, const double& p) { return Point(A.x * p, A.y * p); }
inline Point operator / (const Point& A, const double& p) { return Point(A.x / p, A.y / p); }

inline int dcmp(const double& x) { if(fabs(x) < eps) return 0; else return x < 0 ? -1 : 1; }

inline double Cross(const Point& A, const Point& B) { return A.x * B.y - A.y * B.x; } /// 叉积
inline double Dot(const Point& A, const Point& B) { return A.x * B.x + A.y * B.y; } /// 点积
inline double Length(const Point& A) { return sqrt(Dot(A, A)); } /// 向量长度
inline double Angle(const Point& A, const Point& B) { return acos(Dot(A, B) / Length(A) / Length(B)); } /// 向量A,B夹角

inline Point GetLineIntersection(const Point P, const Point v, const Point Q, const Point w) {///求直线p + v*t 和 Q + w*t 的交点,需确保有交点,v和w是方向向量
    Point u = P - Q;
    double t = Cross(w, u) / Cross(v, w);
    return P + v * t;
}

inline bool Onsegment(Point p, Point a1, Point a2) { /// 判断点p是否在线段p1p2上
    return dcmp(Cross(a1 - p, a2 - p)) == 0 && dcmp(Dot(a1 - p, a2 - p)) <= 0;
}

inline bool SegmentProperInsection(Point a1, Point a2, Point b1, Point b2) { /// 判断线段是否相交
    if(dcmp(Cross(a1 - a2, b1 - b2)) == 0) /// 两线段平行
        return Onsegment(b1, a1, a2) || Onsegment(b2, a1, a2) || Onsegment(a1, b1, b2) || Onsegment(a2, b1, b2);
    Point tmp = GetLineIntersection(a1, a2 - a1, b1, b2 - b1);
    return Onsegment(tmp, a1, a2) && Onsegment(tmp, b1, b2);
}

inline int isPointInpolygon(Point tmp, Point P[], int n) { /// 判断点是否在多边形里
    int wn = 0;
    rep(i, 0, n - 1) {
        if(Onsegment(tmp, P[i], P[(i + 1) % n])) return -1; /// 边界
        int k = dcmp(Cross(P[(i + 1) % n] - P[i], tmp - P[i]));
        int d1 = dcmp(P[i].y - tmp.y);
        int d2 = dcmp(P[(i +1) % n].y - tmp.y);
        if(k > 0 && d1 <= 0 && d2 > 0) wn++;
        if(k < 0 && d2 <= 0 && d1 > 0) wn--;
    }
    if(wn) return 1; /// 外部
    return 0; /// 内部
}

Point P[N];

void solve() {
    Point st, ed;
    double x1, x2, y1, y2;
    scanf("%lf %lf %lf %lf", &st.x, &st.y, &ed.x, &ed.y);
    scanf("%lf %lf %lf %lf", &x1, &y1, &x2, &y2);
    if(x1 > x2) swap(x1, x2);
    if(y1 > y2) swap(y1, y2);
    P[0] = Point(x1, y1);
    P[1] = Point(x1, y2);
    P[2] = Point(x2, y2);
    P[3] = Point(x2, y1);
    rep(i, 0, 2) { /// 判断线段是否和多边形的边相交
        if(SegmentProperInsection(st, ed, P[i], P[i + 1]) == 1) {
            puts("T"); return ;
        }
    }

    if(isPointInpolygon(st, P, 4) || isPointInpolygon(ed, P, 4)) { /// 判断线段是否有一个端点在多边形里或者边界上
        puts("T"); return ;
    }
    puts("F");
}

int main() {
    int _; scanf("%d", &_);

    while(_--) solve();

    return 0;
}

原文地址:https://www.cnblogs.com/Willems/p/12381126.html

时间: 2024-08-02 21:53:34

POJ 1410 (线段是否与多边形相交 + 点是否在多边形内)的相关文章

poj 1410 线段相交判断

http://poj.org/problem?id=1410 Intersection Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 11329   Accepted: 2978 Description You are to write a program that has to decide whether a given line segment intersects a given rectangle. An ex

并行计算大作业之多边形相交(OpenMP、MPI、Java、Windows)

***************************************转载请注明出处:http://blog.csdn.net/lttree******************************************** 吐槽: 话说,相当郁闷,2015年,第一次打开博客,准备总结一下这一年.. 结果博客被封了= =! 今天,终于解封了,换了密码,换了密保.... 但是,写回顾的激情有点退散了.. 明后两天要上课,明天还要验收一个综合设计大作业,再后两天要考试,再后两天继续上课,

POJ 1410 Intersection(线段相交&amp;&amp;判断点在矩形内&amp;&amp;坑爹)

Intersection 大意:给你一条线段,给你一个矩形,问是否相交. 相交:线段完全在矩形内部算相交:线段与矩形任意一条边不规范相交算相交. 思路:知道具体的相交规则之后题其实是不难的,但是还有个坑点就是题目里明明说给的是矩形左上角跟右下角的点,但实际上不是,需要重新判断一下...真坑. 1 struct Point 2 { 3 double x, y; 4 } A, B, C, D; 5 struct Line 6 { 7 Point a, b; 8 } L; 9 10 int n; 11

线段和矩形相交 POJ 1410

1 // 线段和矩形相交 POJ 1410 2 3 // #include <bits/stdc++.h> 4 #include <iostream> 5 #include <cstdio> 6 #include <cstdlib> 7 #include <algorithm> 8 #include <vector> 9 #include <math.h> 10 using namespace std; 11 #defin

POJ 1410 Intersection(线段相交&amp;amp;&amp;amp;推断点在矩形内&amp;amp;&amp;amp;坑爹)

Intersection 大意:给你一条线段,给你一个矩形,问是否相交. 相交:线段全然在矩形内部算相交:线段与矩形随意一条边不规范相交算相交. 思路:知道详细的相交规则之后题事实上是不难的,可是还有个坑点就是题目里明明说给的是矩形左上角跟右下角的点,但实际上不是,须要又一次推断一下...真坑. struct Point { double x, y; } A, B, C, D; struct Line { Point a, b; } L; int n; double xmult(Point p1

poj 1410 Intersection (判断线段与矩形相交 判线段相交)

题目链接 Intersection Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 12040   Accepted: 3125 Description You are to write a program that has to decide whether a given line segment intersects a given rectangle. An example: line: start point:

POJ 1410 Intersection --几何,线段相交

题意: 给一条线段,和一个矩形,问线段是否与矩形相交或在矩形内. 解法: 判断是否在矩形内,如果不在,判断与四条边是否相交即可.这题让我发现自己的线段相交函数有错误的地方,原来我写的线段相交函数就是单纯做了两次跨立实验,在下图这种情况是错误的: 这样的话线段与右边界的两次跨立实验(叉积<=0)都会通过,但是并不相交. 所以要加快速排斥. 还有就是这题题目说给出的不一定是左上角,右下角依次的顺序.所以干脆重新自己定义左上角,右下角. 代码: #include <iostream> #inc

poj 2653 线段与线段相交

Pick-up sticks Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 11884   Accepted: 4499 Description Stan has n sticks of various length. He throws them one at a time on the floor in a random way. After finishing throwing, Stan tries to fin

poj 1269 线段与线段相交

Intersecting Lines Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 13605   Accepted: 6049 Description We all know that a pair of distinct points on a plane defines a line and that a pair of lines on a plane will intersect in one of three