1. 理论方法
- 问题
如何判断点 P P P是否在被 P 1 P 2 P 3 P 4 P_1P_2P_3P_4 P1P2P3P4四个点围成的矩形框内?
- 方法
如果在矩形内:点 P P P与矩形4个角的连线与任意轴形成的夹角都为锐角。可以用向量的点乘判断角度是否为锐角。具体方法如下图所示。
所以可以通过下列公式判断:
点 P 位 于 矩 形 框 内 ⇔ { ∠ P P 1 P 4 < 90 ∠ P P 1 P 2 < 90 ∠ P P 3 P 4 < 90 ∠ P P 3 P 2 < 90 ⇔ { P 1 P ⇀ ∗ P 1 P 4 ⇀ > 0 P 1 P ⇀ ∗ P 1 P 2 ⇀ > 0 P 3 P ⇀ ∗ P 3 P 4 ⇀ > 0 P 3 P ⇀ ∗ P 3 P 2 ⇀ > 0 点P位于矩形框内\Leftrightarrow{\left\{\begin{array}{l}\angle PP_1P_4<90\\\angle PP_1P_2<90\\\angle PP_3P_4<90\\\angle PP_3P_2<90\end{array}\right.}\Leftrightarrow{\left\{\begin{array}{l}\overset\rightharpoonup{P_1P}\ast\overset\rightharpoonup{P_1P_4}\;>0\\\overset\rightharpoonup{P_1P}\ast\overset\rightharpoonup{P_1P_2}\;>0\\\overset\rightharpoonup{P_3P}\ast\overset\rightharpoonup{P_3P_4}\;>0\\\overset\rightharpoonup{P_3P}\ast\overset\rightharpoonup{P_3P_2}\;>0\end{array}\right.} 点P位于矩形框内⇔⎩⎪⎪⎨⎪⎪⎧∠PP1P4<90∠PP1P2<90∠PP3P4<90∠PP3P2<90⇔⎩⎪⎪⎪⎪⎨⎪⎪⎪⎪⎧P1P⇀∗P1P4⇀>0P1P⇀∗P1P2⇀>0P3P⇀∗P3P4⇀>0P3P⇀∗P3P2⇀>0
2. 算法实现
#include<iostream>
struct MPoint
{
double x;
double y;
};
struct RectPoint
{
MPoint p1;
MPoint p2;
MPoint p3;
MPoint p4;
};
bool isPointInRect(MPoint p, RectPoint rect)
{
if ((rect.p1.x - p.x) * (rect.p1.x - rect.p4.x) + (rect.p1.y - p.y) * (rect.p1.y - rect.p4.y) < 0)
return false;
if (((rect.p1.x - p.x) * (rect.p1.x - rect.p2.x) + (rect.p1.y - p.y) * (rect.p1.y - rect.p2.y)) < 0)
return false;
if (((rect.p3.x - p.x) * (rect.p3.x - rect.p4.x) + (rect.p3.y - p.y) * (rect.p3.y - rect.p4.y)) < 0)
return false;
if (((rect.p3.x - p.x) * (rect.p3.x - rect.p2.x) + (rect.p3.y - p.y) * (rect.p3.y - rect.p2.y)) < 0)
return false;
return true;
}
int main(int argc,char *argv[])
{
RectPoint rect;
MPoint p;
//添加矩形框点
rect.p1.x = 1;
rect.p1.y = 0;
rect.p2.x = -1;
rect.p2.y = 0;
rect.p3.x = 0;
rect.p3.y = 1;
rect.p4.x = 0;
rect.p4.y = -1;
p.x = 0.5;
p.y = 0.5;
std::cout<<"("<<p.x<<", "<<p.y<<")"<<"是否在矩形框内:"<<std::boolalpha<<isPointInRect(p, rect)<<std::endl;//1 or 0 use noboolalpha
p.x = 0.5;
p.y = 3.0;
std::cout<<"("<<p.x<<", "<<p.y<<")"<<"是否在矩形框内:"<<std::boolalpha<<isPointInRect(p, rect)<<std::endl;//1 or 0 use noboolalpha
return 1;
}
输出:
(0.5, 0.5)是否在矩形框内:true
(0.5, 3)是否在矩形框内:false