【计算几何各种知识点总结】[不定期补充]

线段相交

判断两线段是否相交

判断两个线段是否相交,要先想一下两条线段之间都有什么样的位置关系。
1.相离
【计算几何各种知识点总结】[不定期补充]_第1张图片
2.相交
【计算几何各种知识点总结】[不定期补充]_第2张图片
3.重合

4.平行
【计算几何各种知识点总结】[不定期补充]_第3张图片
观察了上面4个图片 可以明显的观察到 相交与其他3种的不同
一条线段的两个端点分别在另一条线段的两边
了解了这些加上叉乘就可以进行计算了
Ps:如果不了解叉乘的话必须先了解下叉乘,但我相信能做到求线段相交的人一定对叉乘有了全方位的了解
首先我们知道如果两个点在在一条线段两侧 那么对于线段两端与这两个点分别做叉乘计算取得的积一定是小于0的
可以得到以下结论
【计算几何各种知识点总结】[不定期补充]_第4张图片
Ps:以下线段表示的为向量
(CDxDA)*(CDxDB)<0;
(ABxBD)*(ABxBC)<0;
其实想也很好想
如果两个线段不想交那么势必存在一条线段的两个端点在另一条线段同侧,上述式子就不能满足。
所以通过计算上述式子也就能知道两线段是不是相交了。
但是在实际计算中如果数据量非常大的话那么我们总是计算4遍叉乘的话会很麻烦
所以要考虑更简单的判断两条线不相交的办法来排除一些情况,当然也只能排除一些情况而已,但即使这样也能使整个程序运行的快一些。
我们可以通过判断这两条线段的四个点的关系来淘汰很多点:
(这部分证明并没有什么意义,大家想想即可明白,在此就不赘述了,支架以代码形式给出)
max(s1.x,e1.x) < min(s2.x,e2.x)
max(s2.x,e2.x) < min(s1.x,e1.x)
max(s1.y,e1.y) < min(s2.y,e2.y)
max(s2.y,e2.y) < min(s1.y,e1.y)
这4中情况都是不相交的

======
上述已经介绍了如何判断线段相交,该上代码了

bool IsIntersected(point s1,point e1,point s2,point e2)//两个线段相交
{
    return(max(s1.x,e1.x)>=min(s2.x,e2.x))&&
           (max(s2.x,e2.x)>=min(s1.x,e1.x))&&
           (max(s1.y,e1.y)>=min(s2.y,e2.y))&&
           (max(s2.y,e2.y)>=min(s1.y,e1.y))&&
           (multi(s1,s2,e1)*multi(s1,e1,e2)>0)&&
           (multi(s2,s1,e2)*multi(s2,e2,e1)>0);
}

————————————————————————

求两圆相交面积

两个圆的位置一共有五种情况
1.内含 2.内切 3.相交 4.外切 5.外离
在计算几何中 内含与内切 可以当做同一种情况 外切与外离 可以当做同一种情况
Ps:如果有疑问可以自己画一画图 就会明白了

所以在计算几何中只要分成3种情况就行了
先定义 d为两圆圆心距离

1.外离

外离
这种情况下d>=r1+r2
两圆间没有相交的部分
所以相交面积是0

2.内含
【计算几何各种知识点总结】[不定期补充]_第5张图片
内含
这种情况下 大圆把小圆全部覆盖
相交的面积就是校园的面积 PI * r1 * r1
此情况下 d<=r大-r小
写成代码就是d <= fabs(r1 - r2)

3.相交
【计算几何各种知识点总结】[不定期补充]_第6张图片
相交
相交的部分可以分成 大小两个圆上弧ab与直线ab围成的图形
即可看作
S扇形abc1-S△abc1+S扇形abc2-S△abc2<=>
S扇形abc1+S扇形abc2-S□ac1bc2;
根据中学学的扇形的面积公式可以推到如下

ang1 = acos((r1 * r1 + d * d - r2 * r2) / 2. / r1 / d)
ang2 = acos((r2 * r2 + d * d - r1 * r1) / 2. / r2 / d)
S扇形abc1=ang1 * r1 * r1
S扇形abc2=ang2 * r2 * r2
S□ac1bc2=d * r1 * sin(ang1)

S = ang1 * r1 * r1+ang2 * r2 * r2 - d * r1 * sin(ang1);

======
上述已经介绍了如何计算两圆相交面积,该上代码了

double solve(Round a, Round b)
{
    double d = dis(a, b);
    if (d >= a.r + b.r)
        return 0;
    if (d <= fabs(a.r - b.r))
    {
        double r = a.r < b.r ? a.r : b.r;
        return PI * r * r;
    }
    double ang1 = acos((a.r * a.r + d * d - b.r * b.r) / 2. / a.r / d);
    double ang2 = acos((b.r * b.r + d * d - a.r * a.r) / 2. / b.r / d);
    double ret = ang1 * a.r * a.r + ang2 * b.r * b.r - d * a.r * sin(ang1);
    return ret;
}

你可能感兴趣的:(数学,知识点,几何,计算几何)