c#版点在面内算法

点在面算法,就是放射线算法,原理很简单,就是把一个点向任意方向发射(本程序是向下),如果跟这个面有奇数个交点,证明点在面里面,若是偶数个,则是在外面(包括0),算法主要是优化效率。本人水平有限,算法中肯定有不足之处,请大家海涵!

主要函数如下。

  1.     struct TabPoint
  2.     {
  3.         private double x;
  4.         public double X
  5.         {
  6.             get { return x; }
  7.             set { x = value; }
  8.         }
  9.         private double y;
  10.         public double Y
  11.         {
  12.             get { return y; }
  13.             set { y = value; }
  14.         }
  15.     }
  16.     struct Polygon
  17.     {
  18.         public ArrayList pointsArray;
  19.         private double minx;
  20.         public double MinX
  21.         {
  22.             get { return minx; }
  23.             set { minx = value; }
  24.         }
  25.         private double miny;
  26.         public double MinY
  27.         {
  28.             get { return miny; }
  29.             set { miny = value; }
  30.         }
  31.         private double maxx;
  32.         public double MaxX
  33.         {
  34.             get { return maxx; }
  35.             set { maxx = value; }
  36.         }
  37.         private double maxy;
  38.         public double MaxY
  39.         {
  40.             get { return maxy; }
  41.             set { maxy = value; }
  42.         }
  43.     }
  44.     class Analyse
  45.     {
  46.         private readonly double dis = 0.0000000001; 
  47.         //返回值:true点在面内  false点在面外
  48.         public bool JudgeMeetPoint(TabPoint tpt, ArrayList polygonPtArray)
  49.         {
  50.             int MeetPointNum = 0;
  51.             int PolygonPtSize = polygonPtArray.Count;
  52.             for (int k = 1; k < PolygonPtSize; k++)
  53.             {
  54.                 TabPoint pt1 = (TabPoint)polygonPtArray[k - 1];
  55.                 TabPoint pt2 = (TabPoint)polygonPtArray[k];
  56.                 if (((tpt.X <= pt1.X && tpt.X >= pt2.X) ||
  57.                     (tpt.X >= pt1.X && tpt.X <= pt2.X)) &
  58.                      (tpt.Y >= pt1.Y || tpt.Y >= pt2.Y) &
  59.                      (pt1.X != pt2.X && pt1.Y != pt2.Y))
  60.                 {
  61.                     //判断点是否在线上
  62.                     if (JudgePtInLine(pt1, pt2, tpt))
  63.                     {
  64.                         return true;
  65.                     }
  66.                     //处理特殊情况,交点是端点的情况
  67.                     double temp;
  68.                     //temp相当于被除数(斜率的分母)
  69.                     temp = pt1.X - pt2.X;
  70.                     if (temp >= -dis && temp <= dis)
  71.                     {
  72.                         //处理交点情况
  73.                         double dx = tpt.X - pt1.X;
  74.                         if (dx >= -dis && dx <= dis)
  75.                         {
  76.                             int[] indexs = new int[2];
  77.                             indexs[0] = 0;
  78.                             indexs[1] = 0;
  79.                             GetNotSame(polygonPtArray, k, ref indexs);
  80.                             TabPoint linePt1, linePt2;
  81.                             linePt1 = (TabPoint)polygonPtArray[indexs[0]];
  82.                             linePt2 = (TabPoint)polygonPtArray[indexs[1]];
  83.                             if (k > indexs[0])
  84.                             {
  85.                                 break;
  86.                             }
  87.                             else
  88.                             {
  89.                                 k = indexs[0] + 1;
  90.                             }
  91.                             if (tpt.Y > pt1.Y && ((tpt.X >= linePt1.X && tpt.X <= linePt2.X) ||
  92.                                 (tpt.X >= linePt2.X && tpt.X <= linePt1.X)))
  93.                                 MeetPointNum++;
  94.                         }
  95.                     }
  96.                     else
  97.                     {
  98.                         double kk, bb;
  99.                         double MeetPtY, MeetPtX;
  100.                         kk = (pt1.Y - pt2.Y) / (pt1.X - pt2.X);
  101.                         bb = pt1.Y - kk * pt1.X;
  102.                         MeetPtY = kk * tpt.X + bb;
  103.                         MeetPtX = tpt.X;
  104.                         //处理特殊情况,交点是端点的情况
  105.                         double dx, dy, dx2, dy2;
  106.                         dx = MeetPtX - pt1.X;
  107.                         dy = MeetPtY - pt1.Y;
  108.                         dx2 = MeetPtX - pt2.X;
  109.                         dy2 = MeetPtY - pt2.Y;
  110.                         if ((dx >= -dis && dx <= dis && dy >= -dis
  111.                             && dy <= dis))
  112.                         {
  113.                             TabPoint pt3;
  114.                             if (k == 1)
  115.                             {
  116.                                 pt3 = (TabPoint)polygonPtArray[PolygonPtSize - 2];
  117.                             }
  118.                             else
  119.                             {
  120.                                 pt3 = (TabPoint)polygonPtArray[k - 2];
  121.                             }
  122.                             //提取交点的上下两点分别在垂线的两侧
  123.                             if (tpt.Y > MeetPtY && ((MeetPtX >= pt3.Y && MeetPtX <= pt2.X) ||
  124.                                 (MeetPtX >= pt2.X && MeetPtX <= pt3.X)))
  125.                                 MeetPointNum++;
  126.                         }
  127.                         else if (!(dx2 >= -dis && dx2 <= dis && dy2 >= -dis
  128.                                     && dy2 <= dis))
  129.                         {
  130.                             if (tpt.Y > MeetPtY)
  131.                                 MeetPointNum++;
  132.                         }
  133.                     }
  134.                 }
  135.             }
  136.             if (MeetPointNum % 2 == 1)
  137.                 return true;
  138.             else
  139.                 return false;
  140.         }
  141.         //判断点是否在线上
  142.         private bool JudgePtInLine(TabPoint tpt1, TabPoint tpt2, TabPoint tpt)
  143.         {
  144.             double dx1 = GetDistance(tpt1, tpt2);
  145.             double dx2 = GetDistance(tpt, tpt1);
  146.             double dx3 = GetDistance(tpt, tpt2);
  147.             double dx = dx3 + dx2 - dx1;
  148.             if (dx >= -0.0000000001 && dx <= 0.0000000001)
  149.             {
  150.                 return true;
  151.             }
  152.             return false;
  153.         }
  154.         //求取两点之间的距离
  155.         private double GetDistance(TabPoint tpt1, TabPoint tpt2)
  156.         {
  157.             double x = tpt1.X - tpt2.X;
  158.             if (x <= 0)
  159.             {
  160.                 x = -x;
  161.             }
  162.             double y = tpt1.Y - tpt2.Y;
  163.             if (y <= 0)
  164.             {
  165.                 y = -y;
  166.             }
  167.             return System.Math.Sqrt(x * x + y * y);
  168.         }
  169.         //在链表中获取x轴不相同的点
  170.         private void GetNotSame(ArrayList pointArray, int index, ref int[] indexs)
  171.         {
  172.             indexs[0] = indexs[1] = -1;
  173.             int size = pointArray.Count;
  174.             TabPoint buftpt, tpt;
  175.             tpt = (TabPoint)pointArray[index];
  176.             for (int i = index; i < size; i++)
  177.             {
  178.                 buftpt = (TabPoint)pointArray[i];
  179.                 if (buftpt.X != tpt.X)
  180.                 {
  181.                     indexs[0] = i;
  182.                     break;
  183.                 }
  184.             }
  185.             if (indexs[0] == -1)
  186.             {
  187.                 for (int i = 0; i < size; i++)
  188.                 {
  189.                     buftpt = (TabPoint)pointArray[i];
  190.                     if (buftpt.X != tpt.X)
  191.                     {
  192.                         indexs[0] = i;
  193.                         break;
  194.                     }
  195.                 }
  196.             }
  197.             for (int j = index; j >= 0; j--)
  198.             {
  199.                 buftpt = (TabPoint)pointArray[j];
  200.                 if (buftpt.X != tpt.X)
  201.                 {
  202.                     indexs[1] = j;
  203.                     break;
  204.                 }
  205.             }
  206.             if (indexs[1] == -1)
  207.             {
  208.                 for (int j = size - 1; j >= 0; j--)
  209.                 {
  210.                     buftpt = (TabPoint)pointArray[j];
  211.                     if (buftpt.X != tpt.X)
  212.                     {
  213.                         indexs[1] = j;
  214.                         break;
  215.                     }
  216.                 }
  217.             }
  218.         }
  219.         public bool JudgeInRect(TabPoint minPt,TabPoint maxPt,TabPoint pt)
  220.         {
  221.             if (pt.X >= minPt.X && pt.X <= maxPt.X && pt.Y >= minPt.Y && pt.Y <= maxPt.Y)
  222.             {
  223.                 return true;
  224.             }
  225.             else
  226.             {
  227.                 return false;
  228.             }
  229.         }
  230.     }

你可能感兴趣的:(算法,优化,C#)