(二維)判斷一個點是否在凸多邊形內 & 已知圓上三點求圓心和半徑


一、判斷一個點是否在凸多邊形內 

根據向量叉乘的右手定則:

右手除姆指外的四指合並,姆指與其他四指垂直,四指由A向量的方向握向B向量的方向,這時姆指的指向就是A,B向量向量積的方向。就是說,AB向量積的方向垂直於AB向量確定的平面。如下圖所示:

 

根據右手定則判斷點是否在凸多邊形內原理(原文鏈接:https://blog.csdn.net/qq_35465996/article/details/100054558):

二維向量叉乘,最終會得到一個(0,0,z)的向量,z的正負方向符合右手定則。已知凸多邊形質心在多邊形內,如果一點在凸多邊形內部,則這個點一定屬於質心與多邊形邊的內部;反之,點拘於圖形外。
如圖,做點至多邊形頂點構成多條向量,按照某個方向(順時針/逆時針),則必然存在相鄰向量的向量積彼此反向,即點在圖形外,如p b pbpbXp c pcpc與p c pcpcXp d pdpd,根據右手定則,知叉乘結果必然相反。

將圖多邊形所有點和點p連線,按照順時針/逆時針,相鄰向量做叉乘,得到的相鄰結果里面有異號的,即為外點。否則點在凸多邊形內

C++代碼:

 1 #include <iostream>
 2 #include <array>
 3 #include <vector>
 4 
 5 using namespace std;
 6 using vector2d = array<double, 2>;
 7 
 8 //向量積
 9 double crossProduct(vector2d &p1, vector2d &p2)
10 {
11     return (p1[0]*p2[1]-p2[0]*p1[1]);
12 }
13 
14 //判定點在凸多邊形內 
15 bool pointInConvexPolygon(vector2d p, vector<vector2d>& polygon)
16 {
17     int i, iNext, i2Next;
18     double preCross, nextCross;
19     vector2d v1, v2, v3;
20     int polySize= polygon.size();
21     
22     if(polySize < 3)
23     {
24         return false;
25     }
26     for(i = 0; i < polySize; i++)
27     {
28         iNext = (i + 1) %  polySize;
29         i2Next = (iNext + 1) % polySize;
30         
31         //注意v1, v2, v3最好歸一化一下,防止圖像坐標過大,導致叉乘結果溢出
32         v1={polygon[i][0]-p[0], polygon[i][1]-p[1]};
33         v2={polygon[iNext][0]-p[0], polygon[iNext][1]-p[1]};
34         preCross = crossProduct(v1,v2);
35         
36         v3={polygon[i2Next][0]-p[0], polygon[i2Next][1]-p[1]};
37         nextCross = crossProduct(v2,v3);
38         
39         if(preCross * nextCross < 0)
40         {
41             return false;
42         }
43     }
44     
45     return true;
46 }
47     
48 int main()
49 {
50     vector<vector2d> poly{{0,0}, {0, 2}, {2, 0}};
51     vector2d p{4, 4};
52     
53     if(pointInConvexPolygon(p, poly))
54     {
55         cout<<"this point is in the polygon.\n";
56     }
57     else
58     {
59         cout<<"this point is not in the polygon.\n";
60     }
61     
62     return 0;
63 }
View Code

 

二、已知圓上三點求圓心和半徑

原文:https://blog.csdn.net/weixin_44957370/article/details/116455334

原理:圓上的任意兩點的連線稱作弦,弦的中垂線必過圓心,取三點組成的兩條弦的中垂線的交點,即為圓心,再通過圓心求半徑.

其中三點坐標為 (dx1,dy1) (dx2,dy2) (dx3,dy3)

h1 h2 是弦的的中垂線的 斜率 x y 為圓心坐標 radius 為半徑

代碼:

double midx1,midy1,midx2,midy2;
double h1,h2;
 
//求前兩個點的中心點
midx1 = (dx1 + dx2) / 2;
midy1 = (dy1 + dy2) / 2;
 
//兩條垂線斜率乘積為 -1
h1 = - (dx2 - dx1) / (dy2 - dy1);
 
//求后兩個點的中心點
midx2 = (dx2 + dx3) / 2;
midy2 = (dy2 + dy3) / 2;
 
//兩條垂線斜率乘積為 -1
h2 = - (dx3 - dx2) / (dy3 - dy2);
 
//對應的垂線表示為
 
// y = h1(x - midx1) + midy1;
// y = h2(x - midx2) + midy2;
 
//轉化得
double x = (midy2 - midy1 + midx1*h1 - midx2*h2) / (h1 - h2);
double y = h1 * ( x - midx1) + midy1;
 
double radius = _hypot(fabs(x - dx1), fabs(y - dy1));
 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM