天气与日历 切换到窄版

 找回密码
 立即注册
中国膜结构网
十大进口膜材评选 十大国产膜材评选 十大膜结构设计评选 十大膜结构公司评选
查看: 158|回复: 0

判断点在多边形内算法的C++实现

[复制链接]
  • TA的每日心情
    开心
    半小时前
  • 签到天数: 20 天

    [LV.4]偶尔看看III

    115

    主题

    11

    回帖

    1393

    积分

    管理员

    积分
    1393
    QQ
    发表于 2024-3-16 09:08:56 | 显示全部楼层 |阅读模式
    1. #include<iostream>
    2. #include <cmath>
    3. #include <vector>
    4. #include <algorithm>
    5. #define EPSILON 0.000001
    6. using namespace std;
    7. //二维double矢量
    8. struct  Vec2d
    9. {
    10.         double x, y;
    11.         Vec2d()
    12.         {
    13.                 x = 0.0;
    14.                 y = 0.0;
    15.         }
    16.         Vec2d(double dx, double dy)
    17.         {
    18.                 x = dx;
    19.                 y = dy;
    20.         }
    21.         void Set(double dx, double dy)
    22.         {
    23.                 x = dx;
    24.                 y = dy;
    25.         }
    26. };
    27. //判断点在线段上
    28. bool IsPointOnLine(double px0, double py0, double px1, double py1, double px2, double py2)
    29. {
    30.         bool flag = false;
    31.         double d1 = (px1 - px0) * (py2 - py0) - (px2 - px0) * (py1 - py0);
    32.         if ((abs(d1) < EPSILON) && ((px0 - px1) * (px0 - px2) <= 0) && ((py0 - py1) * (py0 - py2) <= 0))
    33.         {
    34.                 flag = true;
    35.         }
    36.         return flag;
    37. }
    38. //判断两线段相交
    39. bool IsIntersect(double px1, double py1, double px2, double py2, double px3, double py3, double px4, double py4)
    40. {
    41.         bool flag = false;
    42.         double d = (px2 - px1) * (py4 - py3) - (py2 - py1) * (px4 - px3);
    43.         if (d != 0)
    44.         {
    45.                 double r = ((py1 - py3) * (px4 - px3) - (px1 - px3) * (py4 - py3)) / d;
    46.                 double s = ((py1 - py3) * (px2 - px1) - (px1 - px3) * (py2 - py1)) / d;
    47.                 if ((r >= 0) && (r <= 1) && (s >= 0) && (s <= 1))
    48.                 {
    49.                         flag = true;
    50.                 }
    51.         }
    52.         return flag;
    53. }
    54. //判断点在多边形内
    55. bool Point采用In采用Polygon采用2D(double x, double y, const vector<Vec2d> &POL)
    56. {       
    57.         bool isInside = false;
    58.         int count = 0;
    59.        
    60.         //
    61.         double minX = DBL采用MAX;
    62.         for (int i = 0; i < POL.size(); i++)
    63.         {
    64.                 minX = std::min(minX, POL[i].x);
    65.         }
    66.         //
    67.         double px = x;
    68.         double py = y;
    69.         double linePoint1x = x;
    70.         double linePoint1y = y;
    71.         double linePoint2x = minX -10;                        //取最小的X值还小的值作为射线的终点
    72.         double linePoint2y = y;
    73.         //遍历每一条边
    74.         for (int i = 0; i < POL.size() - 1; i++)
    75.         {       
    76.                 double cx1 = POL[i].x;
    77.                 double cy1 = POL[i].y;
    78.                 double cx2 = POL[i + 1].x;
    79.                 double cy2 = POL[i + 1].y;
    80.                                
    81.                 if (IsPointOnLine(px, py, cx1, cy1, cx2, cy2))
    82.                 {
    83.                         return true;
    84.                 }
    85.                 if (fabs(cy2 - cy1) < EPSILON)   //平行则不相交
    86.                 {
    87.                         continue;
    88.                 }
    89.                 if (IsPointOnLine(cx1, cy1, linePoint1x, linePoint1y, linePoint2x, linePoint2y))
    90.                 {
    91.                         if (cy1 > cy2)                        //只保证上端点+1
    92.                         {
    93.                                 count++;
    94.                         }
    95.                 }
    96.                 else if (IsPointOnLine(cx2, cy2, linePoint1x, linePoint1y, linePoint2x, linePoint2y))
    97.                 {
    98.                         if (cy2 > cy1)                        //只保证上端点+1
    99.                         {
    100.                                 count++;
    101.                         }
    102.                 }
    103.                 else if (IsIntersect(cx1, cy1, cx2, cy2, linePoint1x, linePoint1y, linePoint2x, linePoint2y))   //已经排除平行的情况
    104.                 {
    105.                         count++;
    106.                 }
    107.         }
    108.        
    109.         if (count % 2 == 1)
    110.         {
    111.                 isInside = true;
    112.         }
    113.         return isInside;
    114. }
    115. int main()
    116. {       
    117.         //定义一个多边形(六边形)
    118.         vector<Vec2d> POL;       
    119.         POL.push采用back(Vec2d(268.28, 784.75));
    120.         POL.push采用back(Vec2d(153.98, 600.60));
    121.         POL.push采用back(Vec2d(274.63, 336.02));
    122.         POL.push采用back(Vec2d(623.88, 401.64));
    123.         POL.push采用back(Vec2d(676.80, 634.47));
    124.         POL.push采用back(Vec2d(530.75, 822.85));
    125.         POL.push采用back(Vec2d(268.28, 784.75));                                //将起始点放入尾部,方便遍历每一条边
    126.                
    127.         //
    128.         if (Point采用In采用Polygon采用2D(407.98, 579.43, POL))
    129.         {
    130.                 cout << "点(407.98, 579.43)在多边形内" << endl;
    131.         }
    132.         else
    133.         {
    134.                 cout << "点(407.98, 579.43)在多边形外" << endl;
    135.         }
    136.         //
    137.         if (Point采用In采用Polygon采用2D(678.92, 482.07, POL))
    138.         {
    139.                 cout << "点(678.92, 482.07)在多边形内" << endl;
    140.         }
    141.         else
    142.         {
    143.                 cout << "点(678.92, 482.07)在多边形外" << endl;
    144.         }
    145.         return 0;
    146. }
    复制代码

     

     

     

     

    判断点在多边形内算法的C++实现
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|Archiver|中国膜结构网|中国膜结构协会|进口膜材|国产膜材|ETFE|PVDF|PTFE|设计|施工|安装|车棚|看台|污水池|中国膜结构网_中国空间膜结构协会

    GMT+8, 2024-11-5 06:11 , Processed in 0.167354 second(s), 28 queries .

    Powered by Discuz! X3.5

    © 2001-2024 Discuz! Team.

    快速回复 返回顶部 返回列表