线段交(向量运算)

Posted quicksilverx

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线段交(向量运算)相关的知识,希望对你有一定的参考价值。

题目描述:

给定 $n$ 条线段,求相交的线段对数

(计算几何初步学习题~)

对于向(矢)量 $a , b$ 的叉乘,结果是一个标量,绝对值为 $a,b$ 所成平行四边形的面积 $S$ 。

若 $a$ X $b>0$ , 则可知 $b$ 在 $a$ 逆时针方向,反之亦同,而值为 $0$ 则共线(可以反向)。      (我也不知道为什么,还没学那么深就先记下结论8)

以此可以判断两条线段共线问题: 将线段转为向量,若线段 $AB$ 插在 $CD$ 内,则一定有 $AC$ 与 $AD$ 分别在 $AB$ 的不同反向,即相乘的值小于等于 $0$。

对于 $CD$ 的情况亦同。

注意可能有精度上的问题,需要设置一个 $EPS$

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<cmath>
 4 #define R register
 5 const double EPS = 1e-9;
 6 using namespace std;
 7 int n;
 8 struct Node
 9     double x,y;
10 S[105],T[105];
11 inline Node operator -(Node u, Node v)//点坐标相减得到向量
12 
13     return (Node)u.x - v.x, u.y - v.y;
14 
15 inline double operator *(Node u,Node v)//向量×乘
16 
17     return u.x * v.y - u.y * v.x;
18   
19 int main()
20 
21     int Ans = 0;
22     scanf("%d",&n);
23     for(R int i = 1; i <= n; i++)
24         scanf("%lf%lf%lf%lf",&S[i].x,&S[i].y,&T[i].x,&T[i].y);
25     for(R int i = 1; i < n; i++)
26         for(R int j = i + 1; j <= n; j++)
27         
28             if(((T[i] - S[i]) * (S[j] - S[i])) * ((T[i] - S[i]) * (T[j] - S[i])) <= EPS && ((T[j] - S[j]) * (S[i] - S[j])) * ((T[j] - S[j]) * (T[i] - S[j])) <= EPS)
29                 ++Ans;
30         
31     printf("%d",Ans);
32     return 0;
33 

 

以上是关于线段交(向量运算)的主要内容,如果未能解决你的问题,请参考以下文章

向量及其坐标表示

求两条平行线上的 n 条线段与端点的交点数

两条线段间的位置 (叉积)

半平面交复习

向量及向量运算

POJ 3304 Segments 基础线段交判断