面試的時候被問到如何判斷扇形和圓是否相交,當時也是比較懵的,刷leetcode不會碰到這種問題。我大概分了幾個情況進行討論,並且用到了求點到直線的距離公式。面試官後來提示說從幾何的角度考慮,最好不要去用方程求解的角度去想,,,大概想到了向量點乘和叉乘,但是當時沒寫出來。後來在網上看部落格大部分也都是去解方程,稍微麻煩一些,現在把自己的思路分享一下,有錯誤歡迎指正。
我們用兩個端點表示線段,用乙個點和半徑表示圓
typedef pairpoint;
point l1(-1.1,0), l2(5, 0.9), c1(0, 0);
float r;
首先點和圓形的拓撲關係很好計算,根據端點和圓形的關係分成三種情況,即兩個端點都在圓形內,乙個端點在圓形內,兩個端點都不在圓形內。第一種情況不相交,第二種情況相交,第三種情況需要進一步討論。
對這三種情況進行判別只需要乙個點點距離公式:
float pointdis(point p1, point p2)
bool incircle(point p, point c1, float r)
typedef pairvector2d;
有了向量能做的事情就多了,不需要用點到直線的距離公式,也不需要對直線用公式建模(需要判斷特殊情況),計算角度也很方便。下面看一下叉乘:
float crossproduct(vector2d v1, vector2d v2)
二維空間下,叉乘的結果是∣a∣
∗∣b∣
∗sin
θ|a|*|b|*sin\theta
∣a∣∗∣b
∣∗si
nθ,θ
\theta
θ是aa
a和bb
b兩個邊的夾角,其實二維空間下叉乘結果是有正負號的(表示沿隱藏的z軸方向還是其反方向),這裡我們不需要用到這個特性,所以可以直接取絕對值。
下面看一下點乘:
float dotproduct(vector2d v1, vector2d v2)
點乘的結果是∣a∣
∗∣b∣
∗cos
θ|a|*|b|*cos\theta
∣a∣∗∣b
∣∗co
sθ,顯然cos
θcos\theta
cosθ
的正負可以表示乙個角是銳角還是鈍角。
好的我們有了向量、點乘和叉乘,接下來思考如何避免對直線建模後再去計算距離,以及如何去判斷角度:
向量表示:
vector2d vecl2_l1(l1.first - l2.first, l1.second - l2.second);
vector2d vecl1_l2(-vecl2_l1.first, -vecl2_l1.second);
vector2d vecc1_l1(l1.first - c1.first, l1.second - c1.second);
vector2d vecc1_l2(l2.first - c1.first, l2.second - c1.second);
叉乘計算距離:
float dis = abs(crossproduct(vecc1_l1, vecl2_l1) / pointdis(l1, l2));
沒錯,就是這麼簡單。接下來用點乘判斷夾角:
if (dis > r) return false;
bool flag = dotproduct(vecl1_l2, vecc1_l2) && dotproduct(vecl2_l1, vecc1_l1);
如果兩個夾角都是銳角,flag為true,反之flag為false,全部**如下:
#include #include using namespace std;
typedef pairpoint;
typedef pairvector2d;
// 點距
float pointdis(point p1, point p2)
// ×乘
float crossproduct(vector2d v1, vector2d v2)
// 點乘
float dotproduct(vector2d v1, vector2d v2)
//點是否在圓內
bool incircle(point p, point c1, float r)
//線段與圓是否相交
bool judgecircleandline(point l1, point l2, point c1, float r)
int main()
{ point l1(-1.1,0), l2(0,1.1), c1(0, 0);
std::cout 暫時寫到這裡,有問題歡迎指正,後邊會繼續些扇形的問題。。
判斷線段是否與圓相交模板
判斷線段和圓是否相交 判斷圓和線段相交,分兩種情況 1.如圖a所示,當圓心與線段的距離大於圓的半徑時,線段與圓肯定不相交 推導過程 此處補充直線方程的五種形式 一般式為ax by c 0,它的優點就是它可以表示平面上的任意一條直線,僅此而已.斜截式y kx b,就不能表示垂直x軸的直線x a.點斜式...
C 判斷線段是否相交
c 判斷線段是否相交 線段是否相交,一種是從幾何上就是判斷兩個線段有沒有交點,還有一種是通過向量叉乘 也就是向量積 來判斷。因為向量叉乘的結果是乙個垂直於原來兩個向量的新向量,可以簡單的理解為垂直於原來兩向量所在平面的向量。我們來看圖。線段是否相交 線段p1p2的p1點 線段p1p2的p2點 線段q...
C 判斷線段是否相交
線段是否相交,一種是從幾何上就是判斷兩個線段有沒有交點,還有一種是通過向量叉乘 也就是向量積 來判斷。因為向量叉乘的結果是乙個垂直於原來兩個向量的新向量,可以簡單的理解為垂直於原來兩向量所在平面的向量。我們來看圖 線段是否相交 線段p1p2的p1點 線段p1p2的p2點 線段q1q2的q1點 線段q...