判断任意一点是否在矩形内(矩形可能与坐标轴有一定夹角)

1. 理论方法

  • 问题

如何判断点 P P P是否在被 P 1 P 2 P 3 P 4 P_1P_2P_3P_4 P1​P2​P3​P4​四个点围成的矩形框内?

  • 方法

如果在矩形内:点 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位于矩形框内⇔⎩⎪⎪⎨⎪⎪⎧​∠PP1​P4​<90∠PP1​P2​<90∠PP3​P4​<90∠PP3​P2​<90​⇔⎩⎪⎪⎪⎪⎨⎪⎪⎪⎪⎧​P1​P⇀​∗P1​P4​⇀​>0P1​P⇀​∗P1​P2​⇀​>0P3​P⇀​∗P3​P4​⇀​>0P3​P⇀​∗P3​P2​⇀​>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
上一篇:makefile的简单应用纪录(将多个文件各生成一个.o文件)


下一篇:第八次实验