利用向量判斷線段和圓是否相交

2021-10-06 08:15:10 字數 2611 閱讀 6215

面試的時候被問到如何判斷扇形和圓是否相交,當時也是比較懵的,刷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...