uva191 Intersection(线段之间相交)

题意:是否线段与矩形相交,线段在矩形内部也是相交。

公式:p1*p2=(x1*x2,y1*y2)(内积),p1xp2=(x1*y2,x2*y1)(外积)

判断q是否在线段p1-p2上面,根据(p1-q)x(p2-q)=0来判断q是否在直线p1-p2上。利用内积(p1-q)*(p2-q)<0判断q是否在p1-p2之间。

p1-p2,q1-q2的交点:

(x,y)=p1+(p2-p1)*((q2-q1)x(q1-p1)/((q2-q1)x(p2-p1)));

注意:左顶点和右下角的坐标输入,不是按照先左上角然后右下角这个顺序输入的,总之你需要判断得出左上角和右下角的坐标。

#include <iostream>
#include<cstdio>
#include<cmath>
using namespace std;
#define EPS 1e-10

struct point
{
    double a,b;
    point(){}
    point(double a,double b):a(a),b(b){}
    point operator +(point p)
    {
        return point(p.a+a,p.b+b);
    }
    point operator -(point p)
    {
        return point(a-p.a,b-p.b);
    }
    point operator *(double p)
    {
        return point(a*p,b*p);
    }
    double dot(point p)//内积
    {
        return (p.a*a+p.b*b);
    }
    double det(point p)//外积
    {
        return (a*p.b-b*p.a);
    }
};
point p1,p2,q1,q2;
//判断q是否在线段p1-p2上
bool on_str(point p1,point p2,point q)
{
    return (abs((p1-q).det(p2-q))<EPS&&(p1-q).dot(p2-q)<EPS);
}
//求两直线交点
point intersection(point p1,point p2,point q1,point q2)
{
    return p1+(p2-p1)*((q2-q1).det(q1-p1)/(q2-q1).det(p2-p1));
}
bool judge(point q1,point q2)
{
    if(abs((p1-p2).det(q1-q2))<EPS)
    {
         if(on_str(p1,p2,q1)||on_str(p1,p2,q2)||on_str(q1,q2,p1)||on_str(q1,q2,p2))//判断是否有重合
             return 1;
        else
             return 0;
    }
    point r=intersection(p1,p2,q1,q2);
    return on_str(p1,p2,r)&&on_str(q1,q2,r);
}
int main()
{
    int n;
    scanf("%d",&n);
    while(n--)
    {
        scanf("%lf%lf%lf%lf%lf%lf%lf%lf",&p1.a,&p1.b,&p2.a,&p2.b,&q1.a,&q1.b,&q2.a,&q2.b);
        if(q1.a>q2.a)
            swap(q1.a,q2.a);
        if(q1.b<q2.b)
            swap(q1.b,q2.b);
        if(p1.a>=q1.a&&p1.a<=q2.a&&p1.b<=q1.b&&p1.b>=q2.b&&p2.a>=q1.a&&p2.a<=q2.a&&p2.b<=q1.b&&p2.b>=q2.b)
        {
            printf("T\n");
        }
        else{
            if(judge(q1,point(q2.a,q1.b))||judge(q1,point(q1.a,q2.b))||judge(q2,point(q2.a,q1.b))||judge(q2,point(q1.a,q2.b)))
                printf("T\n");
            else
                printf("F\n");
        }

    }

    return 0;
}
时间: 2025-02-01 23:42:33

uva191 Intersection(线段之间相交)的相关文章

URAL 1966 Cycling Roads 点在线段上、线段是否相交、并查集

F - Cycling Roads Description When Vova was in Shenzhen, he rented a bike and spent most of the time cycling around the city. Vova was approaching one of the city parks when he noticed the park plan hanging opposite the central entrance. The plan had

zoj 1010 Area 判断线段是否相交(把线段扩充一倍后 好处理) + 多边形求面积

题目来源: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=10 题意:  给定n个点的, 如果这n个点不能形成多边形 以及 n < 3 时, 输出, "Impossible",  否则 输出 多边形的面积. 分析: 这题主要在 分析  n 个点 是否形成 多边形.  枚举 每条边,  看 这条边 是否与 其他 n - 3 条边 不规范相交. (当处理 其他 边时, 我们采用 扩充线段一倍) 代码如下: con

判断平面上两线段是否相交

计算几何基础——矢量和叉积 矢量 如果一条线段的端点是有次序之分的话,那么这种线段就称为 有向线段,如果有向线段p1p2的起点p1在坐标的原点,则可以把它称为矢量 p2 矢量的加减 设二维矢量 P = (x1, y1), Q = (x2, y2),则 P + Q = (x1 + x2, y1 + y2), P - Q = (x1 - x2, y1 - y2),且有 P + Q = Q + P, P - Q = -(Q - P) 矢量叉积 设矢量 P = (x1, y1), Q = (x2, y2

Jack Straws(判断线段是否相交 + 并查集)

/** http://acm.tzc.edu.cn/acmhome/problemdetail.do?&method=showdetail&id=1840  题意: 判断线段是否相交  (包括间接相交) 输入: N(代表有n条线段) sx  sy  ex  ey(一条直线的两端点的坐标) : : : a b(判断第a条和第b条线段是否相交) : : : 0 0输入0 0 询问结束 输出:若相交输出  CONNECTED 否则         NOT CONNECTED */ #includ

判断两线段是否相交

今日集训第一日,遇到了判断线段相交问题.跟面积问题一样,这个同样可以用叉积来解决. 数学原理证明: 首先引出计算几何学中一个最基本的问题:如何判断向量在的顺时针方向还是逆时针方向? 把p0定为原点,p1的坐标是(x1,y1),p2的坐标是(x2,y2).向量的叉积(cross product)实际上就是矩阵的行列式: 代码实现: 1 int direction(Point p0, Point p1, Point p2) { 2 int px02 = p2.x - p0.x; 3 int py02

判断两个线段是否相交

我们的问题是这样的:给定一条线段的起点为$A_1$.终点为$A_2$,另一条线段的起点为$B_1$.终点为$B_2$,问线段$A_1A_2$和线段$B_1B_2$是否相交? 我们首先解释一下,两条线段相交的概念是指,存在一个点,这个点同时在两条线段上. 方法一(解方程法): 容易知道,线段$A_1A_2$上的点的集合为$A = A_1 * (1 - r_1) + A_2 * r_1$,其中$r_1 \in [0, 1]$:同理,线段$B_1B_2$上的点的集合为$B = B_1 * (1 - r

codeForce-589D Boulevard(判断线段是否相交)

题目大意:n个人.一个区间.每个人都会在某个时间段内按相同的速度(所有人的速度都一样,都是1或-1)在他的区间内从一个端点走到另一个端点(只走一次).问每个人会与几个人碰面. 题目分析:将时间看成一个维度,区间位置看成另一个维度.那么每个人的状态便构成了一条二维线段.只需判断有几条线段与该线段相交. 判断两平面线段是否相交: 设线段1的两端点分别为A.B,线段2的两端点分别为C.D. 当两条线段平行时,只需要判断点C或点D是否在线段AB上即可.点C在线段AB上的判断:先判断向量CA与向量CB是否

判断两线段是否相交 模板

1 struct point 2 { 3 double x, y; 4 point( double _x = 0, double _y = 0 ) 5 { 6 x = _x; 7 y = _y; 8 } 9 point operator-( point t ) 10 { 11 return point( x - t.x, y - t.y ); 12 } 13 double operator*( point t ) 14 { 15 return x * t.y - y * t.x; 16 } 17

zoj 1648 判断线段是否相交

链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=648 Circuit Board Time Limit: 2 Seconds      Memory Limit: 65536 KB On the circuit board, there are lots of circuit paths. We know the basic constrain is that no two path cross each other,