判断扇形和圆是否相交
面试的时候被问到如何判断扇形和圆是否相交,当时也是比较懵的,刷leetcode不会碰到这种问题。我大概分了几个情况进行讨论,并且用到了求点到直线的距离公式。面试官后来提示说从几何的角度考虑,最好不要去用方程求解的角度去想,,,大概想到了向量点乘和叉乘,但是当时没写出来。后来在网上看博客大部分也都是去解方程,稍微麻烦一些,现在把自己的思路分享一下,有错误欢迎指正。
一般大家首先会考虑到分成扇形边和弧段部分分别判断吧,我们先看一下如何判断线段是否和圆形相交:
线段和圆形是否相交
我们用两个端点表示线段,用一个点和半径表示圆
typedef pair<float, float> Point;
Point l1(-1.1,0), l2(5, 0.9), c1(0, 0);
float R;
首先点和圆形的拓扑关系很好计算,根据端点和圆形的关系分成三种情况,即两个端点都在圆形内,一个端点在圆形内,两个端点都不在圆形内。第一种情况不相交,第二种情况相交,第三种情况需要进一步讨论。
对这三种情况进行判别只需要一个点点距离公式:
float pointDis(Point p1, Point p2)
{
return sqrt((p1.first - p2.first) * (p1.first - p2.first) + (p1.second - p2.second) * (p1.second - p2.second));
}
bool inCircle(Point p, Point c1, float R)
{
float dis = pointDis(p, c1);
if (dis < R)
return true;
return false;
}
下面对第三种情况进行进一步的讨论:
如果圆心到这个直线的距离小于半径,且垂足落在线段上,那么相交,否则不相交。为了完成这个计算,我们引入向量:
typedef pair<float, float> vector2d;
有了向量能做的事情就多了,不需要用点到直线的距离公式,也不需要对直线用公式建模(需要判断特殊情况),计算角度也很方便。下面看一下叉乘:
float crossProduct(vector2d v1, vector2d v2)
{
return (v1.first * v2.second - v1.second * v2.first);
}
二维空间下,叉乘的结果是 ∣ a ∣ ∗ ∣ b ∣