线段交(向量运算)

题目描述:

给定 $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 }

猜你喜欢

转载自www.cnblogs.com/QuickSilverX/p/10988944.html