首页 > 其他分享 >POJ 1410 Intersection

POJ 1410 Intersection

时间:2023-07-18 19:32:08浏览次数:39  
标签:return POINT int double POJ 1410 rec Intersection plist


判断线段与多边形是否相交。


模板:

#include <stdio.h>
#include <math.h>
#include <algorithm>

using namespace std;
#define Pi 3.14159265358979
#define PRECISION 1e-8

//点
typedef struct {
    double x,y;
} POINT;

//直线两点的表达
struct LINE{
    POINT p1,p2;
};

//多边形结构体
struct POLY{
    int n;
    double area;
    POINT plist[15];
};

//与0作比较,小于精度则认为是和0相等
int cmpzero(double d){
    return (fabs(d) < PRECISION)?0:(d>0?1:-1);
}

//向量点积
double dotdet(double x1,double y1,double x2,double y2){
    return x1*x2 + y1 * y2;
}

//向量叉积
double cross_det(double x1,double y1,double x2,double y2){
    return x1*y2 - x2*y1;
}

//右手螺旋定则,1:a在cd右侧;-1:a在cd左侧;0:三点共线
int cross(POINT &a,POINT &c,POINT &d){
    return cmpzero(cross_det(a.x - c.x,a.y - c.y,d.x - c.x,d.y - c.y));
}

//在cross(a,c,d) == 0的基础上,可判断点a是否在cd内部
int between(POINT &a,POINT &c,POINT &d){
    return cmpzero(dotdet(c.x - a.x,c.y - a.y, d.x - a.x, d.y - a.y)) != 1;
}

//两线段相交情况:0:不想交,1:规范相交,-1:不规范相交(交于端点或重合)
int seg_intersect(POINT &a,POINT &b,POINT &c,POINT &d){
    int a_cd = cross(a,c,d);
    if(a_cd == 0 && between(a,c,d)){return 2;}
    int b_cd = cross(b,c,d);
    if(b_cd == 0 && between(b,c,d)){return 2;}
    int c_ab = cross(c,a,b);
    if(c_ab == 0 && between(c,a,b)){return 2;}
    int d_ab = cross(d,a,b);
    if(d_ab == 0 && between(d,a,b)){return 2;}
    if((a_cd^b_cd) == -2 && (c_ab ^ d_ab) == -2){
        return 1;
    }
    return 0;
}

//使用有向面积法判断点是否在多边形内
int point_in_poly(POLY &p,POINT &pt){
    double s = 0.0;
    for(int i = 0; i < p.n; i++){
        s += fabs(cross_det(p.plist[i].x - pt.x,p.plist[i].y - pt.y,p.plist[(i+1)%p.n].x - pt.x,p.plist[(i+1)%p.n].y - pt.y));
    }
    if(cmpzero(s - p.area) == 0 ){
        return 1;
    }
    return 0;
}

//计算多边形面积
void area(POLY &p){
    double s = p.plist[0].y * (p.plist[p.n - 1].x - p.plist[1].x);
    for(int i = 1; i < p.n; i++){
        s += p.plist[i].y * (p.plist[i - 1].x - p.plist[(i+1)%p.n].x);
    }
    p.area = s;
}

//判断线段是否与多边形相交
int rec_seg_intersect(POLY &p,LINE &l){
    if(point_in_poly(p,l.p1) && point_in_poly(p,l.p2)){return 1;}
    else if(seg_intersect(l.p1,l.p2,p.plist[0],p.plist[1])
            || seg_intersect(l.p1,l.p2,p.plist[1],p.plist[2])
            || seg_intersect(l.p1,l.p2,p.plist[2],p.plist[3])
            || seg_intersect(l.p1,l.p2,p.plist[3],p.plist[0]))
            return 1;
    return 0;
}

int main() {
    int n,m,i,min;
    int T;
    POLY rec;
    LINE l;
    double xleft,ytop,xright,ybottom;
    scanf("%d",&T);
    while(T--){
        scanf("%lf%lf%lf%lf",&l.p1.x,&l.p1.y,&l.p2.x,&l.p2.y);
        scanf("%lf%lf%lf%lf",&xleft,&ytop,&xright,&ybottom);
        if(xleft > xright){swap(xleft,xright);}
        if(ytop < ybottom){swap(ytop,ybottom);}
        rec.n = 4;
        rec.plist[0].x = xleft, rec.plist[0].y = ytop;
        rec.plist[1].x = xleft, rec.plist[1].y = ybottom;
        rec.plist[2].x = xright, rec.plist[2].y = ybottom;
        rec.plist[3].x = xright, rec.plist[3].y = ytop;
        area(rec);
        puts(rec_seg_intersect(rec,l)?"T":"F");
    }
    return 0;
}





标签:return,POINT,int,double,POJ,1410,rec,Intersection,plist
From: https://blog.51cto.com/u_16192154/6767503

相关文章

  • java bean、EJB、POJO区别
    JavaBean、EJB、POJO区别在Java开发中,我们经常会听到三个词,JavaBean、EJB和POJO。它们在Java开发中有着不同的角色和用法。本文将详细介绍它们的区别,并给出相关的代码示例。JavaBeanJavaBean是一种Java语言规范,用于描述一种可重用的组件。它是一种特殊的类,遵循一些特定的命......
  • 对目标元素进行监听 - addListener和IntersectionObserver
    在web的构建中,经常需要对元素进行监听,例如监听元素是否出现在可视范围内。我们可以通过addEventListener来监听滚动,计算元素距离顶部的位置对元素的变更来做出反应。但是长时间大量的触发事件反而对网页性能影响很大,使用节流的话其实也只是浅浅的优化一下性能。有没有其他思路可......
  • POJ3468 A Simple Problem with Integers
    ASimpleProblemwithIntegers题目链接:ASimpleProblemwithIntegers题意给定\(N\)个数,可以选择\([l,r]\),让下标在区间内的值都增加一定值,或者输出下标在区间内元素的和。思路可以用带懒标记的线段树写,但是代码太长,不利于编写。这里有一个利用差分借助树状数组实现的写法......
  • poj 1064 高精度 二分
    CablemasterTimeLimit: 1000MSMemoryLimit: 10000KTotalSubmissions: 32191Accepted: 6888DescriptionInhabitantsoftheWonderlandhavedecidedtoholdaregionalprogrammingcontest.TheJudgingCommitteehasvolunteeredandhaspromisedtoorganizethe......
  • poj 2236 Wireless Network 并查集
    WirelessNetworkTimeLimit: 10000MSMemoryLimit: 65536KTotalSubmissions: 20499Accepted: 8608DescriptionAnearthquaketakesplaceinSoutheastAsia.TheACM(AsiaCooperatedMedicalteam)havesetupawirelessnetworkwiththelapcomputers,butanun......
  • POJ 2109 Power of Cryptography 数学题 double和float精度和范围
    PowerofCryptographyTimeLimit:1000MSMemoryLimit:30000KTotalSubmissions:21354Accepted:10799DescriptionCurrentworkincryptographyinvolves(amongotherthings)largeprimenumbersandcomputingpowersofnumbersamongtheseprimes.Workint......
  • poj 1182 食物链 并查集
    食物链TimeLimit:1000MSMemoryLimit:10000KTotalSubmissions:56297Accepted:16500Description动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形。A吃B,B吃C,C吃A。现有N个动物,以1-N编号。每个动物都是A,B,C中的一种,但是我们并不知道它到底是哪一种......
  • Cesium学习笔记3——加载topojson和Geojson
    在根目录下新建bucket.css@import"../Build/CesiumUnminified/Widgets/widgets.css";@import"../Build/CesiumUnminified/Widgets/lighter.css";html{height:100%}body{background:#000;color:#eee;font-family:sans-serif;font-size:9pt;padding:0;margin:0;w......
  • POJ 2976:Dropping tests 01 分数规划
    DroppingtestsTimeLimit: 1000MS MemoryLimit: 65536KTotalSubmissions: 12291 Accepted: 4293DescriptionInacertaincourse,youtake n tests.Ifyouget ai outof bi questionscorrectontest i,yourcumulativeaverageisdefinedtobe.Gi......
  • 【线段树】 POJ 3667 Hotel
    这道题和那道HDOJ3308LCIS比较像。。那道题目我就写了超久,当时是不确定保存什么信息。。这道题也写了很久,主要是各种低级错误,找错找了很久,超级火。。。。#include<iostream>#include<sstream>#include<algorithm>#include<vector>#include<queue>#include<stack>#inc......