点在面内的算法

来源:互联网 发布:十二星相 知乎 编辑:程序博客网 时间:2024/04/30 15:24
放射线算法,就是把一个点向任意方向发射(本程序是向下),如果跟这个面有奇数个交点,证明点在面里面,若是偶数个,则是在外面(包括0), 
struct TabPoint     {         private double x;         public double X         {             get { return x; }             set { x = value; }         }         private double y;         public double Y         {             get { return y; }             set { y = value; }         }     }     struct Polygon     {         public ArrayList pointsArray;         private double minx;         public double MinX         {             get { return minx; }             set { minx = value; }         }         private double miny;         public double MinY         {             get { return miny; }             set { miny = value; }         }         private double maxx;         public double MaxX         {             get { return maxx; }             set { maxx = value; }         }         private double maxy;         public double MaxY         {             get { return maxy; }             set { maxy = value; }         }     }     class Analyse     {         private readonly double dis = 0.0000000001;          //返回值:true点在面内  false点在面外         public bool JudgeMeetPoint(TabPoint tpt, ArrayList polygonPtArray)         {             int MeetPointNum = 0;             int PolygonPtSize = polygonPtArray.Count;             for (int k = 1; k < PolygonPtSize; k++)             {                 TabPoint pt1 = (TabPoint)polygonPtArray[k - 1];                 TabPoint pt2 = (TabPoint)polygonPtArray[k];                 if (((tpt.X <= pt1.X && tpt.X >= pt2.X) ||                     (tpt.X >= pt1.X && tpt.X <= pt2.X)) &                      (tpt.Y >= pt1.Y || tpt.Y >= pt2.Y) &                      (pt1.X != pt2.X && pt1.Y != pt2.Y))                 {                     //判断点是否在线上                     if (JudgePtInLine(pt1, pt2, tpt))                     {                         return true;                     }                     //处理特殊情况,交点是端点的情况                     double temp;                     //temp相当于被除数(斜率的分母)                     temp = pt1.X - pt2.X;                     if (temp >= -dis && temp <= dis)                     {                         //处理交点情况                         double dx = tpt.X - pt1.X;                         if (dx >= -dis && dx <= dis)                         {                             int[] indexs = new int[2];                             indexs[0] = 0;                             indexs[1] = 0;                             GetNotSame(polygonPtArray, k, ref indexs);                             TabPoint linePt1, linePt2;                             linePt1 = (TabPoint)polygonPtArray[indexs[0]];                             linePt2 = (TabPoint)polygonPtArray[indexs[1]];                             if (k > indexs[0])                             {                                 break;                             }                             else                             {                                 k = indexs[0] + 1;                             }                             if (tpt.Y > pt1.Y && ((tpt.X >= linePt1.X && tpt.X <= linePt2.X) ||                                 (tpt.X >= linePt2.X && tpt.X <= linePt1.X)))                                 MeetPointNum++;                         }                     }                     else                     {                         double kk, bb;                         double MeetPtY, MeetPtX;                         kk = (pt1.Y - pt2.Y) / (pt1.X - pt2.X);                         bb = pt1.Y - kk * pt1.X;                         MeetPtY = kk * tpt.X + bb;                         MeetPtX = tpt.X;                         //处理特殊情况,交点是端点的情况                         double dx, dy, dx2, dy2;                         dx = MeetPtX - pt1.X;                         dy = MeetPtY - pt1.Y;                         dx2 = MeetPtX - pt2.X;                         dy2 = MeetPtY - pt2.Y;                         if ((dx >= -dis && dx <= dis && dy >= -dis                             && dy <= dis))                         {                             TabPoint pt3;                             if (k == 1)                             {                                 pt3 = (TabPoint)polygonPtArray[PolygonPtSize - 2];                             }                             else                             {                                 pt3 = (TabPoint)polygonPtArray[k - 2];                             }                             //提取交点的上下两点分别在垂线的两侧                             if (tpt.Y > MeetPtY && ((MeetPtX >= pt3.Y && MeetPtX <= pt2.X) ||                                 (MeetPtX >= pt2.X && MeetPtX <= pt3.X)))                                 MeetPointNum++;                         }                         else if (!(dx2 >= -dis && dx2 <= dis && dy2 >= -dis                                     && dy2 <= dis))                         {                             if (tpt.Y > MeetPtY)                                 MeetPointNum++;                         }                     }                 }             }             if (MeetPointNum % 2 == 1)                 return true;             else                 return false;         }         //判断点是否在线上         private bool JudgePtInLine(TabPoint tpt1, TabPoint tpt2, TabPoint tpt)         {             double dx1 = GetDistance(tpt1, tpt2);             double dx2 = GetDistance(tpt, tpt1);             double dx3 = GetDistance(tpt, tpt2);             double dx = dx3 + dx2 - dx1;             if (dx >= -0.0000000001 && dx <= 0.0000000001)             {                 return true;             }             return false;         }         //求取两点之间的距离         private double GetDistance(TabPoint tpt1, TabPoint tpt2)         {             double x = tpt1.X - tpt2.X;             if (x <= 0)             {                 x = -x;             }             double y = tpt1.Y - tpt2.Y;             if (y <= 0)             {                 y = -y;             }             return System.Math.Sqrt(x * x + y * y);         }         //在链表中获取x轴不相同的点         private void GetNotSame(ArrayList pointArray, int index, ref int[] indexs)         {             indexs[0] = indexs[1] = -1;             int size = pointArray.Count;             TabPoint buftpt, tpt;             tpt = (TabPoint)pointArray[index];             for (int i = index; i < size; i++)             {                 buftpt = (TabPoint)pointArray;                 if (buftpt.X != tpt.X)                 {                     indexs[0] = i;                     break;                 }             }             if (indexs[0] == -1)             {                 for (int i = 0; i < size; i++)                 {                     buftpt = (TabPoint)pointArray;                     if (buftpt.X != tpt.X)                     {                         indexs[0] = i;                         break;                     }                 }             }             for (int j = index; j >= 0; j--)             {                 buftpt = (TabPoint)pointArray[j];                 if (buftpt.X != tpt.X)                 {                     indexs[1] = j;                     break;                 }             }             if (indexs[1] == -1)             {                 for (int j = size - 1; j >= 0; j--)                 {                     buftpt = (TabPoint)pointArray[j];                     if (buftpt.X != tpt.X)                     {                         indexs[1] = j;                         break;                     }                 }             }         }         public bool JudgeInRect(TabPoint minPt,TabPoint maxPt,TabPoint pt)         {             if (pt.X >= minPt.X && pt.X <= maxPt.X && pt.Y >= minPt.Y && pt.Y <= maxPt.Y)             {                 return true;             }             else             {                 return false;             }         }     }

原创粉丝点击