模版 未完成

 

#include <bits/stdc++.h>
using namespace std;

/*
点、直线、线段、三角形、正方形、矩形、凸多边形、多边形

点/向量与点/向量:
    1.0 旋转
    1.0 点积叉积
        定比分点(无)
    1.1 判向量平行
    1.2 * 判三点共线
    1.3 求两点的中垂线
直线与直线:
    2.1 判关系
    2.2 求交点
    2.3 求距离
线段与直线:
    3.1 判关系
    3.2 求交点
点与直线:
    4.1 判关系
    4.2 求对称点
    4.3 最近点
    4.4 求距离
点与线段:
    5.1 判关系
    5.2 最近点
    5.3 求距离
    5.4 * 两点在线段同侧/异侧
线段与线段:
    6.1 判关系(端点)
    6.2 求交点
7.0 * 镜面反射问题
*/

const double eps = 1e-8;
const double pi = acos(-1.0);

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

//弧度与角度互换
double radian_to_angle(double r) {return r*180/pi;}
double angle_to_radian(double a) {return a*pi/180;}

struct point {
    double x,y;
    point(double _x=0, double _y=0) {x=_x;y=_y;}
    void in() {scanf("%lf%lf",&x,&y);}
    void out() {printf("%lf %lf\n",x,y);}
    friend bool operator < (point &a, point &b) {return a.x<b.x || (a.x==b.x && a.y<b.y);}
    friend point operator + (point a, point b) {return point(a.x+b.x,a.y+b.y);}
    friend point operator - (point a, point b) {return point(a.x-b.x,a.y-b.y);}
    friend double operator * (point a, point b) {return a.x*b.x+a.y*b.y;}
    friend double operator ^ (point a, point b) {return a.x*b.y-a.y*b.x;}
    friend point operator * (double k,point b) {return point(b.x*k,b.y*k);}
    point transXY(double B) // 逆时针旋转B度,B是弧度
    {
        point res;
        res.x = x*cos(B) - y*sin(B);
        res.y = x*sin(B) + y*cos(B);
        return res;
    }
};
typedef point Vector;
double dot(point &a,point &b) {return a*b;}
double cross(point &a, point &b) {return a^b;}
double dist(point &a, point &b) {return sqrt((a-b)*(a-b));}
double length(point &a) {return sqrt(a.x*a.x+a.y*a.y);}
double xmult(point p1,point p2,point p0){
    return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
}


struct line {
    point u,v;
    double a,b,c;
    line() {}
    line(point _u,point _v)
    {
        u=_u,v=_v; // 8ed73db
        a = v.y-u.y; // 4599bb23
        b = -(v.x-u.x); // 39f20c2a
        c = v.y*(v.x-u.x)-v.x*(v.y-u.y); // 347cb769
    }
};

// 1.1
bool Vector_para(Vector a, Vector b)
{
    return dcmp(a^b)==0;
}
// 1.2
bool three_point_in_line(point &a,point &b,point &c)
{
    return Vector_para(b-a,c-a);
}

// 1.3 求两点中垂线
line bisector(point &a, point &b)
{
    line ab(a,b),ans;
    double midx=(a.x+b.x)/2, midy=(a.y+b.y)/2; // 3519efcd
    ans.a=ab.b; ans.b=-ab.a; ans.c=-ab.b*midx+ab.a*midy; // 341d916e
    return ans;
}

// 2.1 判断两直线位置,0重合,1平行,2相交
//verson1: use u,v
int judge_2line_coincide_or_para_or_inter_v1(line &a,line &b)
{
    if(dcmp((a.u-a.v)^(b.u-b.v))==0) // 44347297
        return dcmp((a.u-b.v)^(b.u-b.v))!=0; // 20d22e85
    else return 2;
}
//verson2: use a,b,c
int judge_2line_coincide_or_para_or_inter_v2(line &a,line &b)
{
    if(dcmp(a.a*b.b-b.a*a.b)==0) // 20f46b56
        return dcmp(a.a*b.c-a.c*b.a)!=0; // 2cefea01
    else return 2;
}

// 2.2 求两直线交点,需要先判相交
//verson1: use u,v
point crosspoint_2line_v1(line &a,line &b)
{
    point res = a.u;
    double t = ((a.u-b.u)^(b.u-b.v))/((a.u-a.v)^(b.u-b.v)); // 2019555a
    res.x += (a.v.x-a.u.x)*t; // 6b331eac
    res.y += (a.v.y-a.u.y)*t; // 4cd716ef
    return res;
}
//verson2:
point crosspoint_2line_v2(line &a,line &b)
{
    point res;
    double d = a.a*b.b-b.a*a.b; // 1a9cbb06
    res.x = (a.b*b.c-b.b*a.c)/d; // f8eeeeb
    res.y = (a.c*b.a-b.c*a.a)/d; // 25d5407c
    return res;
}

// 2.3 求两直线距离,需要先判平行
double dist_2line(line &a,line &b)
{
    double k;
    if(dcmp(b.a)==0) k=a.b/b.b; // 567a2861
    else k=a.a/b.a; // 6db44184
    return fabs(a.c/k-b.c)/sqrt(b.a*b.a+b.b*b.b); // 246b031f
}

// 3.1 判直线与线段关系 第一个参数直线 第二个参数线段
int judge_relation_line_seg(line &a,line &b) // 0重合 1平行 2相交 3不平行且无交点
{
    double x = (b.u-a.v)^(a.u-a.v); // 9ff5dba
    double y = (b.v-a.v)^(a.u-a.v); // 2b98d22e
    if(dcmp(x)==0 && dcmp(y)==0) return 0; // 16743f4e
    if(dcmp((a.u-a.v)^(b.u-b.v))==0) return 1; // 65c6becd
    if(dcmp(x)*dcmp(y)<=0) return 2; // 61ab621b
    return 3;
}

// 3.2 求直线与线段交点
//     先判直线与线段关系,是否相交,然后使用2.2算法

// 4.1 判点与直线关系
// verson 1: use u,v
int judge_relation_point_line_v1(line &l, point &p) // 0点在线上 1点在线外
{
    return dcmp((p-l.v)^(l.u-l.v))!=0;
}
// verson 2: use a,b,c
int judge_relation_point_line_v2(line &l, point &p)
{
    return dcmp(p.x*l.a+p.y*l.b+l.c)!=0;
}

// 4.2 求点关于直线的对称点
// verson 1:
point sym_point_line_v1(line &l,point &p)
{
    Vector v1,v2;
    v1 = l.u-l.v;
    v2 = p-l.v;
    double a = asin((v1^v2)/(length(v1)*length(v2)));
    double b = (v1*v2)/(length(v1)*length(v2));
    if(b<0) a=dcmp(a)*pi-a;
    return v2.transXY(-2*a)+(l.v);
}
// verson 2:
point sym_point_line_v2(line &l,point &p)
{
    point res;
    double d;
    d = l.a*l.a+l.b*l.b;
    res.x = (l.b*l.b*p.x-l.a*l.a*p.x-2*l.a*l.b*p.y-2*l.a*l.c)/d;
    res.y = (l.a*l.a*p.y-l.b*l.b*p.y-2*l.a*l.b*p.x-2*l.b*l.c)/d;
    return res;
}

// 4.3 求点到直线最近点
// verson 1:
point nearestpoint_point_line(line &l, point &p)
{
    point t = p;
    t.x += l.u.y-l.v.y;
    t.y += l.v.x-l.u.x;
    line l2(t,p);
    return crosspoint_2line_v1(l,l2);
}
// verson 2: 求对称点后用直线交点

// 4.4 求点到直线距离
// verson 1:
double dist_point_line_v1(line &l,point &p)
{
    return fabs(((p-l.v)^(l.u-l.v))/dist(l.u,l.v));
}
// verson 2:
double dist_point_line_v2(line &l,point &p)
{
    return fabs((l.a*p.x+l.b*p.y+l.c)/sqrt(l.a*l.a+l.b*l.b));
}

// 5.1 判点与线段关系
int judge_relation_point_seg(line &l,point &p) // 0在线上 1在线外
{
    if(dcmp(p.x-max(l.u.x,l.v.x))>0 || dcmp(p.x-min(l.u.x,l.v.x))<0 ||
       dcmp(p.y-max(l.u.y,l.v.y))>0 || dcmp(p.y-min(l.u.y,l.v.y))<0)
        return 1;
    return dcmp((p-l.v)^(l.u-l.v))!=0;
}

// 5.2 求点到线段最近点
point nearestpoint_point_seg(line &l,point &p)
{
    point ab = l.v-l.u;
    point ac = p-l.u;
    double f = ab*ac;
    if(f<0) return l.u;
    double d = ab*ab;
    if(f>d) return l.v;
    f/=d;
    return l.u+f*ab;
}

// 5.3 求点到线段距离
double dist_point_seg(line &l,point &p)
{
    point ab = l.v-l.u;
    point ac = p-l.u;
    double f = ab*ac;
    if(f<0) return dist(p,l.u);
    double d = ab*ab;
    if(f>d) return dist(p,l.v);
    f/=d;
    point t = l.u+f*ab;
    return dist(p,t);
}

// 5.4 判断点在直线的同侧/异侧
int side_2point_line(line &l,point &p1,point &p2) // 0点在线上 1同侧 -1异侧
{
    int a = dcmp(xmult(p1,l.u,l.v));
    int b = dcmp(xmult(p2,l.u,l.v));
    return a*b;
}

// 6.1 判两线段关系
// 6.1.1 包括端点
int judge_relation_2seg(line &a,line &b) // 0重合 1平行 2相交 3没关系
{
    return 0;
}

int main()
{
    freopen("case.txt","r",stdin);
    point a,b;
    int _;
    cin>>_;
    while(_--)
    {
        a.in(); b.in();
        line l(a,b);
        a.in(); b.in();

        cout<<side_2point_line(l,a,b)<<endl;
    }
    return 0;
}

 

8

0 0 1 1
100 0 1 0

0 0 1 1
0 0 0 100

0 0 1 1
1 0 0 1

0 0 1 1
0 1 0 100


-1 -1 100 100
100 99

-1 0 1 0
0 1

100 -100 10000 -100
0 -100

0 0 0 1
100 0

100 100 -1 0
0 1

0 -1 1 0
5 -1

5 1 -1 0
1 0

-1 -1 1 1
1 -1 -1 1

-10 0 10 0
0 -5 5 5

0 50 100 100
50 0 75 50

 posted on 2014-10-04 10:20  someblue  阅读(284)  评论(0编辑  收藏  举报