德莱联盟 计算几何 线段相交

难度:1
 
描述

欢迎来到德莱联盟。。。。

德莱文。。。

德莱文在逃跑,卡兹克在追。。。。

我们知道德莱文的起点和终点坐标,我们也知道卡兹克的起点和 终点坐标,问:卡兹克有可能和德莱文相遇吗?,并且保证他们走的都是直线。

 
输入
几组数据,一个整数T表示T组数据
每组数据 8个实数,分别表示德莱文的起点和终点坐标,以及卡兹克的起点和终点坐标
输出
如果可能 输出 Interseetion,否则输出 Not Interseetion
样例输入
2
-19.74 7.14 22.23 -27.45 -38.79 -5.08 47.51 34.01
-8.61 9.91 -32.47 6.47 -3.81 -16.1 7.82 -6.37
样例输出
Interseetion
Not Interseetion
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<sstream>
#include<algorithm>
#include<queue>
#include<deque>
#include<iomanip>
#include<vector>
#include<cmath>
#include<map>
#include<stack>
#include<set>
#include<fstream>
#include<memory>
#include<list>
#include<string>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
#define MAXN 2000000003
#define N 21
#define MOD 1000000
#define INF 1000000009
//#define eps 0.00000001
const double PI = acos(-1.0);
double torad(double deg) { return deg / 180 * PI; }

struct Point
{
    double x, y;
    Point(double x = 0, double y = 0) :x(x), y(y) { }
};

typedef Point Vector;

Vector operator + (const Vector& A, const Vector& B) { return Vector(A.x + B.x, A.y + B.y); }
Vector operator - (const Point& A, const Point& B) { return Vector(A.x - B.x, A.y - B.y); }
Vector operator * (const Vector& A, double p) { return Vector(A.x*p, A.y*p); }
Vector operator / (const Vector& A, double p) { return Vector(A.x / p, A.y / p); }

bool operator < (const Point& a, const Point& b)    //结构体运算符的重载
{
    return a.x < b.x || (a.x == b.x && a.y < b.y);
}

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

bool operator == (const Point& a, const Point &b)
{
    return dcmp(a.x - b.x) == 0 && dcmp(a.y - b.y) == 0;
}

//基本运算:
double dist(const Vector& A, const Vector& B) { return sqrt(pow(A.x - B.x, 2) + pow(A.y - B.y, 2)); }
double Dot(const Vector& A, const Vector& B) { return A.x*B.x + A.y*B.y; }//点乘
double Length(const Vector& A) { return sqrt(Dot(A, A)); }
double Angle(const Vector& A, const Vector& B) { return acos(Dot(A, B) / Length(A) / Length(B)); }
double Cross(const Vector& A, const Vector& B) { return A.x*B.y - A.y*B.x; }//叉乘
double Area2(Point A, Point B, Point C) { return Cross(B - A, C - A); }

//向量旋转 rad是弧度
Vector Rotate(const Vector& A, double rad)
{
    return Vector(A.x*cos(rad) - A.y*sin(rad), A.x*sin(rad) + A.y*cos(rad));
}
//点和直线:
//两直线的交点
Point GetLineIntersection(const Point& P, const Point& v, const Point& Q, const Point& w)
{
    Vector u = P - Q; 
        double t = Cross(w, u) / Cross(v, w);
    return P + v*t;
}

//点到直线的距离
double DistanceToLine(const Point& P, const Point& A, const Point& B)
{
    Vector v1 = B - A, v2 = P - A;
    return fabs(Cross(v1, v2)) / Length(v1);
}

//点到线段的距离
double DistanceToSegment(const Point& P, const Point& A, const Point& B)
{
    if (A == B) return Length(P - A);
    Vector v1 = B - A, v2 = P - A, v3 = P - B;
    if (dcmp(Dot(v1, v2)) < 0) return Length(v2);
    else if (dcmp(Dot(v1, v3)) > 0) return Length(v3);
    else return fabs(Cross(v1, v2)) / Length(v1);
}

//点在直线上的投影
Point GetLineProjection(const Point &P, const Point &A, const Point &B)
{
    Vector v = B - A;
    return A + v*(Dot(v, P - A) / Dot(v, v));
}

//线段相交判定
bool SegmentProperIntersection(const Point& a1, const Point& a2, const Point& b1, const Point& b2)
{
    double c1 = Cross(a2 - a1, b1 - a1), c2 = Cross(a2 - a1, b2 - a1),
        c3 = Cross(b2 - b1, a1 - b1), c4 = Cross(b2 - b1, a2 - b1);
    return dcmp(c1)*dcmp(c2)<0 && dcmp(c3)*dcmp(c4)<0;
}


//判断点在线段上(两个端点除外)
bool OnSegment(const Point& p, const Point& a1, const Point& a2)
{
    return dcmp(Cross(a1 - p, a2 - p)) == 0 && dcmp(Dot(a1 - p, a2 - p)) < 0;
}

int main()
{
    Vector a, b, c, d;
    int T;
    scanf("%d", &T);
    while (T--)
    {
        cin >> a.x >> a.y >> b.x >> b.y >> c.x >> c.y >> d.x >> d.y;
        if (SegmentProperIntersection(a, b, c, d))
            printf("Interseetion
");
        else
            printf("Not Interseetion
");
    }
    return 0;
}
原文地址:https://www.cnblogs.com/joeylee97/p/6925005.html