zoukankan      html  css  js  c++  java
  • 判断点是否在多边形内——射线法

      1 //判断射线与也线段是否相交, 相交返回1,不相交返回0,在边上返回-1
    2 int IsIntersectant( CPoint ptStart, CPoint ptEnd, CPoint pd )
    3 {
    4 double tempx = 0;
    5 double tempy = 0;
    6 //记录多边形边的端点坐标;
    7 double startx = ptStart.x;
    8 double starty = ptStart.y;
    9 double endx = ptEnd.x;
    10 double endy = ptEnd.y;
    11
    12 double maxX = startx;
    13 double minX = endx;
    14 if (startx<endx)
    15 {
    16 minX = startx;
    17 maxX = endx;
    18 }
    19
    20 //保证开始点在下(y坐标大),作为下端点
    21 if(starty<endy)
    22 {
    23 double temp=starty;
    24 starty=endy;
    25 endy=temp;
    26 temp=startx;
    27 startx=endx;
    28 endx=temp;
    29 }
    30
    31 //首先排除没有交点的情况
    32 if((pd.y>starty && pd.y>endy) || (pd.y<starty && pd.y<endy)) //水平射线在该直线段的上下两端之外
    33 {
    34 return 0;
    35 }
    36 if(pd.x>startx && pd.x>endx) //水平射线的起点在该直线段的右边
    37 {
    38 return 0;
    39 }
    40
    41 //如果是水平线段,在线段上返回-1,否则返回0
    42 if (starty ==endy)
    43 {
    44 if (pd.x<=maxX&&pd.x>=minX)
    45 {
    46 return -1;
    47 }
    48 return 0;
    49 }
    50
    51 //判断点pd是否是多边形边上的点,通过距离判断
    52 tempx = pd.x - startx;
    53 tempy = pd.y - starty;
    54 double dStartToX = sqrt(tempx*tempx+tempy*tempy);
    55
    56 tempx = pd.x - endx;
    57 tempy = pd.y - endy;
    58 double dXToEnd = sqrt(tempx*tempx+tempy*tempy);
    59
    60 tempx = startx - endx;
    61 tempy = starty - endy;
    62 double dStarToEnd = sqrt(tempx*tempx+tempy*tempy);
    63
    64 if (dStarToEnd == (dStartToX + dXToEnd))
    65 {
    66 return -1;
    67 }
    68
    69 //h_x记录点pd(x,y)引水平线与直线段所在直线的交点x坐标(直线坐标y=kx+b)
    70 double h_x=(pd.y-starty)*(endx-startx)/(endy-starty)+startx;
    71
    72 if(pd.x>h_x)//pd点在交点的右边,则射线与线段不相交
    73 {
    74 return 0;
    75 }
    76 if(pd.y==starty) //水平射线与直线段的上端点相交,不计交点,只考虑与直线段的下端点相交
    77 {
    78 return 0;
    79 }
    80
    81 return 1;
    82
    83 }
    84 BOOL PtInPolygon( CPoint *ptList, int ptCount, CPoint pd )
    85 {
    86 if (ptCount<3)
    87 {
    88 return FALSE;
    89 }
    90
    91 int cross_num = 0;
    92 int iFlag = 0;
    93 //从点pd,向右引水平射线
    94
    95 for(int i=0;i<ptCount-1;i++)
    96 {
    97 iFlag = IsIntersectant(ptList[i], ptList[i+1], pd);
    98 if (iFlag < 0)
    99 {
    100 return TRUE;
    101 }
    102 else
    103 {
    104 cross_num += iFlag;
    105 }
    106 }
    107
    108 //末端点与首端点连接线
    109 iFlag = IsIntersectant(ptList[ptCount-1], ptList[0], pd);
    110 if (iFlag < 0)
    111 {
    112 return TRUE;
    113 }
    114 else
    115 {
    116 cross_num += iFlag;
    117 }
    118
    119 if(cross_num%2==1) //交点个数为奇
    120 {
    121 return TRUE;
    122 }
    123 else if(cross_num%2==0) //交点个数为偶
    124 {
    125 return FALSE;
    126 }
    127
    128 return FALSE;
    129
    130 }
  • 相关阅读:
    如何编译完全使用静态库的可执行文件
    交叉编译jpeglib遇到的问题
    安装SDL遇到的问题
    软链接/硬链接删除事项
    alias命令使用
    Linux下学习摄像头使用
    018 字符串类型及操作
    017 示例3-天天向上的力量
    016 数字类型及操作
    015 基本数据类型
  • 原文地址:https://www.cnblogs.com/hbf369/p/2281559.html
Copyright © 2011-2022 走看看