一、判斷一個點是否在凸多邊形內
根據向量叉乘的右手定則:
右手除姆指外的四指合並,姆指與其他四指垂直,四指由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 }
二、已知圓上三點求圓心和半徑
原文: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));