直线与直线相交 直线与线段相交 线段与线段相交

 

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

struct Point
{
    double x,y;
    Point() {}
    Point(double _x,double _y)
    {
        x = _x,y = _y;
    }
    Point operator -(const Point &b)const
    {
        return Point(x - b.x,y - b.y);
    }
    //叉积
    double operator ^(const Point &b)const
    {
        return x*b.y - y*b.x;
    }
    //点积
    double operator *(const Point &b)const
    {
        return x*b.x + y*b.y;
    }
};

struct Line
{
    Point p,q;
    Line() {};
    Line(Point _p,Point _q)
    {
        p = _p,q = _q;
    }
    //两直线相交求交点
    //第一个值为0表示直线重合,为1表示平行,为2表示相交
    //只有第一个值为2时,交点才有意义
    pair<int,Point> operator &(const Line &b)const
    {
        Point res = p;
        if(sgn((p-q)^(b.p-b.q)) == 0)
        {
            if(sgn((p-b.q)^(b.p-b.q)) == 0)
                return make_pair(0,res);//重合
            else return make_pair(1,res);//平行
        }
        double t = ((p-b.p)^(b.p-b.q))/((p-q)^(b.p-b.q));
        res.x += (q.x-p.x)*t;
        res.y += (q.y-p.y)*t;
        return make_pair(2,res);
    }
};

//判断直线和线段相交
bool Seg_inter_line(Line l1,Line l2) //判断直线l1和线段l2是否相交,<0是把交于线段端点处看做不相交
{
    return sgn((l2.p-l1.q)^(l1.p-l1.q))*sgn((l2.q-l1.q)^(l1.p-l1.q)) < 0;
}

//*判断线段相交
bool inter(Line l1,Line l2)
{
    return
        max(l1.p.x,l1.q.x) >= min(l2.p.x,l2.q.x) &&
        max(l2.p.x,l2.q.x) >= min(l1.p.x,l1.q.x) &&
        max(l1.p.y,l1.q.y) >= min(l2.p.y,l2.q.y) &&
        max(l2.p.y,l2.q.y) >= min(l1.p.y,l1.q.y) &&
        sgn((l2.p-l1.q)^(l1.p-l1.q))*sgn((l2.q-l1.q)^(l1.p-l1.q)) <= 0 &&
        sgn((l1.p-l2.q)^(l2.p-l2.q))*sgn((l1.q-l2.q)^(l2.p-l2.q)) <= 0;
}
时间: 2024-10-09 16:32:48

直线与直线相交 直线与线段相交 线段与线段相交的相关文章

BZOJ1007 水平相交直线

按照斜率排序,我们可以想象如果你能看到大于等于三条直线那么他一定会组成一个下凸包,这样我们只需要判断如果当前这条直线与栈顶第二直线相交点相比于栈顶第二直线与栈顶直线相交点靠左那么他就不满足凸包性质. 画画图想想看. 1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=1000005; 4 double eps=1e-8; 5 bool ans[1000005]; 6 struct node 7 { 8 double k,

(hdu step 5.1.3)Segment set(求与一条线段相交的线段集合中的线段的数量)

题目: Segment set Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 177 Accepted Submission(s): 82   Problem Description A segment and all segments which are connected with it compose a segment set. T

已知直线上两点求直线的一般式方程

一般式方程在计算机领域的重要性 常用的直线方程有一般式 点斜式 截距式 斜截式 两点式等等.除了一般式方程,它们要么不能支持所有情况下的直线(比如跟坐标轴垂直或者平行),要么不能支持所有情况下的点(比如x坐标相等,或者y坐标相等).所以一般式方程在用计算机处理二维图形数据时特别有用. 已知直线上两点求直线的一般式方程 已知直线上的两点P1(X1,Y1) P2(X2,Y2), P1 P2两点不重合.则直线的一般式方程AX+BY+C=0中,A B C分别等于: A = Y2 - Y1 B = X1

主席树/函数式线段树/可持久化线段树

什么是主席树 可持久化数据结构(Persistent data structure)就是利用函数式编程的思想使其支持询问历史版本.同时充分利用它们之间的共同数据来减少时间和空间消耗. 因此可持久化线段树也叫函数式线段树又叫主席树. 可持久化数据结构 在算法执行的过程中,会发现在更新一个动态集合时,需要维护其过去的版本.这样的集合称为是可持久的. 实现持久集合的一种方法时每当该集合被修改时,就将其整个的复制下来,但是这种方法会降低执行速度并占用过多的空间. 考虑一个持久集合S. 如图所示,对集合的

BZOJ 3110 ZJOI 2013 K大数查询 树套树(权值线段树套区间线段树)

题目大意:有一些位置,这些位置上可以放若干个数字.现在有两种操作. 1.在区间l到r上添加一个数字x 2.求出l到r上的第k大的数字是什么 思路:这种题一看就是树套树,关键是怎么套,怎么写.(话说我也不会来着..)最容易想到的方法就是区间线段树套一个权值线段树,但是区间线段树上的标记就会变得异常复杂.所以我们就反过来套,用权值线段树套区间线段树.这样修改操作在外线段树上就变成了单点修改,外线段树就不用维护标记了.在里面的区间线段树上维护标记就容易多了.具体实现见代码. CODE: #includ

hdu 2857 点在直线上的投影+直线的交点

Mirror and Light Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 814    Accepted Submission(s): 385 Problem Description The light travels in a straight line and always goes in the minimal path b

线段与非无限平面相交检测

参考自<游戏编程精粹1>,用该方法除了知道是否相交以外还可以得到相交点,从而用于其他判断. 原文用到了平面方程Ax+By+Cz+D=0,通过三角形求出平面,然后用方程求出线段交点 这里直接使用平面,以下为Unity中的实现代码: using System.Collections; using System.Collections.Generic; using UnityEngine; public class Practice : MonoBehaviour { public Transfor

①使用鼠标随意画线、②画直线(显示直线轨迹)、③画直线(不显示直线轨迹)

①PaintJFrame类 package drawLine; import java.awt.*; import java.awt.event.*; import javax.swing.*; public class PaintJFrame extends JFrame { public PaintJFrame() { super("使用鼠标随意画线"); this.setBounds(400,300,400,300); this.setDefaultCloseOperation(

Unity实现任意两点之间画一条直线——bresenham算法(直线的处理)

在家里闲着没事,在网上看到一个好玩的需求,在亮点之间画一条直线. 听起来很简单,unity就提供了很多的API,不过大部分是以屏幕画一条线类似的方式做的.如果我们需要让部队等 一个集群排列成一条斜线呢? 其实这也和屏幕渲染一条直线的道理是一样的. 屏幕要画一条直线的话,其实也是在屏幕的像素坐标系里面x,y进行赋值,把连续数转换成离散数,放大看的时候,就会看到一条直线其实是一条梯子状的线. 在实际的场景中可以把我们的地图当成一个屏幕,地图最小格子单位当成一个屏幕的像素点,这样就相当于构建了一套屏幕