自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

C#判斷點的位置(區(qū)域內或外)

開發(fā) 后端
本文介紹了c# 判斷點的位置的三種方法及其圖形算法,供大家參考。

C#判斷點的位置方法一 

  1. public int isLeft(Point P0, Point P1,Point P2)  
  2.         {  
  3.             int abc= ((P1.X - P0.X) * (P2.Y - P0.Y) - (P2.X - P0.X) * (P1.Y - P0.Y));  
  4.             return abc;  
  5.                                                           
  6.         }  
  7.  
  8.         private bool PointInFences(Point pnt1, Point[] fencePnts)  
  9.         {  
  10.  
  11.             int wn = 0,j=0; //wn 計數器 j第二個點指針  
  12.             for (int i = 0; i <  fencePnts.Length; i++)  
  13.             {//開始循環(huán)  
  14.                      if (i == fencePnts.Length - 1)  
  15.                          j = 0;//如果 循環(huán)到最后一點 第二個指針指向第一點  
  16.                      else 
  17.                          j = j + 1; //如果不是 ,則找下一點  
  18.  
  19.  
  20.                 if (fencePnts[i].Y < = pnt1.Y) // 如果多邊形的點 小于等于 選定點的 Y 坐標  
  21.                 {  
  22.                     if (fencePnts[j].Y > pnt1.Y) // 如果多邊形的下一點 大于于 選定點的 Y 坐標  
  23.                     {  
  24.                         if (isLeft(fencePnts[i], fencePnts[j], pnt1) > 0)  
  25.                         {  
  26.                             wn++;  
  27.                         }  
  28.                     }  
  29.                 }  
  30.                 else 
  31.                 {  
  32.                     if (fencePnts[j].Y < = pnt1.Y)  
  33.                     {  
  34.                         if (isLeft(fencePnts[i], fencePnts[j], pnt1) <  0)  
  35.                         {  
  36.                             wn--;  
  37.                         }  
  38.                     }  
  39.                 }  
  40.             }  
  41.             if (wn == 0)  
  42.                 return false;  
  43.             else 
  44.                 return true;  
  45.        } 

C#判斷點的位置方法二——c#內置函數:

  1. GraphicsPath myGraphicsPath = new GraphicsPath();   
  2. Region myRegion=new Region();                
  3. myGraphicsPath.Reset();  
  4. Point inputponint = new Point(inputx, inputy);  
  5.  
  6. myGraphicsPath.AddPolygon(points);//points);  
  7.  
  8. myRegion.MakeEmpty();  
  9.  
  10. myRegion.Union(myGraphicsPath);     
  11. //返回判斷點是否在多邊形里  
  12. bool myPoint= myRegion.IsVisible(inputponint);  
  13. this.lblx.Text = myPoint.ToString(); 

圖形算法:

1,面積法。就是看所有邊和目標點組成的三角形面積和是否等于總的多邊形面積,如果相等,則在內部。反之在外部。這種方法計算量較大,用到的主要計算是查乘。

2,夾角和法。參見三樓,判斷所有邊和目標點的夾角和是否為360度。計算量比上面這種方法稍微小點,用到主要是點乘和求模計算。

3,引射線法。就是從該點出發(fā)引一條射線,看這條射線和所有邊的交點數目。如果有奇數個交點,則說明在內部,如果有偶數個交點,則說明在外部。這是所有方法中計算量最小的方法,在光線追蹤算法中有大量的應用。

在C#中的話,有一個Region類,可以直接調用IsVisible判斷是否在這個區(qū)域內部,我估計內部的實現應該是上面說的第三種方法。主要看你的需求是哪種輸入了,如果在C#中,你完全可以用Region類來隱藏內部實現。

C#判斷點的位置的另外一種解決方法:

1.已知點point(x,y)和多邊形Polygon(x1,y1;x2,y2;….xn,yn;);

2.以point為起點,以無窮遠為終點作平行于X軸的直線line(x,y; -∞,y);

3.循環(huán)取得(for(i=0;i< n;i++))多邊形的每一條邊side(xi,yi;xi+1,yi+1),且判斷是否平行于X軸,如果平行continue,否則,i++;

4. 同時判斷point(x,y)是否在side上,如果是,則返回1(點在多邊形

上),否則繼續(xù)下面的判斷;

5.判斷線side與line是否有交點,如果有則count++,否則,i++。

6.判斷交點的總數,如果為奇數則返回0(點在多邊形內),偶數則返回2(點在多邊形外)。

代碼:

  1. /* 射線法判斷點q與多邊形polygon的位置關系,要求polygon為簡單多邊形,頂點逆時針排列  
  2.  
  3. 如果點在多邊形內: 返回0  
  4.  
  5. 如果點在多邊形邊上: 返回1  
  6.  
  7. 如果點在多邊形外: 返回2  
  8.  
  9. */ 
  10.  
  11. const double INFINITY = 1e10;  
  12.  
  13. const double ESP = 1e-5;  
  14.  
  15. const int MAX_N = 1000;  
  16.  
  17.  
  18. struct Point {  
  19.  
  20. double x, y;  
  21.  
  22. };  
  23.  
  24. struct LineSegment {  
  25.  
  26. Point pt1, pt2;  
  27.  
  28. };  
  29.  
  30. typedef vector< Point> Polygon;  
  31.  
  32.  
  33. // 計算叉乘 |P0P1| × |P0P2|  
  34.  
  35. double Multiply(Point p1, Point p2, Point p0)  
  36.  
  37. {  
  38.  
  39. return ( (p1.x - p0.x) * (p2.y - p0.y) - (p2.x - p0.x) * (p1.y - p0.y) );  
  40.  
  41. }  
  42.  
  43. // 判斷線段是否包含點point  
  44.  
  45. bool IsOnline(Point point, LineSegment line)  
  46.  
  47. {  
  48.  
  49. return( ( fabs(Multiply(line.pt1, line.pt2, point)) <  ESP ) &&  
  50.  
  51. ( ( point.x - line.pt1.x ) * ( point.x - line.pt2.x ) < = 0 ) &&  
  52.  
  53. ( ( point.y - line.pt1.y ) * ( point.y - line.pt2.y ) < = 0 ) );  
  54.  
  55. }  
  56.  
  57. // 判斷線段相交  
  58.  
  59. bool Intersect(LineSegment L1, LineSegment L2)  
  60.  
  61. {  
  62.  
  63. return( (max(L1.pt1.x, L1.pt2.x) >= min(L2.pt1.x, L2.pt2.x)) &&  
  64.  
  65. (max(L2.pt1.x, L2.pt2.x) >= min(L1.pt1.x, L1.pt2.x)) &&  
  66.  
  67. (max(L1.pt1.y, L1.pt2.y) >= min(L2.pt1.y, L2.pt2.y)) &&  
  68.  
  69. (max(L2.pt1.y, L2.pt2.y) >= min(L1.pt1.y, L1.pt2.y)) &&  
  70.  
  71. (Multiply(L2.pt1, L1.pt2, L1.pt1) * Multiply(L1.pt2, L2.pt2, L1.pt1) >= 0) &&  
  72.  
  73. (Multiply(L1.pt1, L2.pt2, L2.pt1) * Multiply(L2.pt2, L1.pt2, L2.pt1) >= 0)  
  74.  
  75. );  
  76.  
  77. }  
  78.  
  79. // 判斷點在多邊形內  
  80.  
  81. bool InPolygon(const Polygon& polygon, Point point)  
  82.  
  83. {  
  84.  
  85. int n = polygon.size();  
  86.  
  87. int count = 0;  
  88.  
  89. LineSegment line;  
  90.  
  91. line.pt1 = point;  
  92.  
  93. line.pt2.y = point.y;  
  94.  
  95. line.pt2.x = - INFINITY;  
  96.  
  97.  
  98. forint i = 0; i <  n; i++ ) {  
  99.  
  100. // 得到多邊形的一條邊  
  101.  
  102. LineSegment side;  
  103.  
  104. side.pt1 = polygon[i];  
  105.  
  106. side.pt2 = polygon[(i + 1) % n];  
  107.  
  108.  
  109. if( IsOnline(point, side) ) {  
  110.  
  111. return1 ;  
  112.  
  113. }  
  114.  
  115.  
  116. // 如果side平行x軸則不作考慮  
  117.  
  118. if( fabs(side.pt1.y - side.pt2.y) <  ESP ) {  
  119.  
  120. continue;  
  121.  
  122. }  
  123.  
  124.  
  125. if( IsOnline(side.pt1, line) ) {  
  126.  
  127. if( side.pt1.y > side.pt2.y ) count++;  
  128.  
  129. else if( IsOnline(side.pt2, line) ) {  
  130.  
  131. if( side.pt2.y > side.pt1.y ) count++;  
  132.  
  133. else if( Intersect(line, side) ) {  
  134.  
  135. count++;  
  136.  
  137. }  
  138.  
  139. }  
  140.  
  141.  
  142. if ( count % 2 == 1 ) {return 0;}  
  143.  
  144. else { return 2;}  
  145.  
  146. }  
  147.  

【編輯推薦】

  1. C#代碼與#函數相互調用問題集錦
  2. 如何使用泛型達到代碼重用的目的
  3. 線性鏈表測試方法簡介
  4. 創(chuàng)建一個簡單的線性鏈表
  5. C#事件模型的一個實例
責任編輯:book05 來源: cnblogs
相關推薦

2017-09-18 08:53:28

編程語言ERP補丁管理

2021-12-14 11:42:49

勒索軟件惡意軟件安全

2024-10-09 07:59:10

C#接口信息

2009-08-28 15:38:49

C#實現斷點續(xù)傳

2009-09-23 09:36:34

C#數組

2021-08-30 07:49:32

Javascript西瓜視頻

2022-03-06 20:02:21

監(jiān)聽視頻播放

2009-09-09 10:32:12

C# CheckBox

2009-08-17 07:58:00

C#刪除文件目錄

2024-01-15 00:40:43

C#Java編譯器

2009-08-25 17:15:50

C#隱藏C#重寫C#重載

2009-09-01 18:35:53

C#判斷文件存在

2018-07-26 08:36:35

Azure Funct編程Chef

2009-09-07 05:40:16

C#窗體位置C#窗體大小

2024-04-02 09:26:07

C#中文數字編程語言

2009-09-02 18:28:00

C#鼠標位置

2018-04-13 06:46:43

無服務器單元測試IT云

2009-09-02 15:53:27

C#判斷字符串應用

2009-08-14 13:52:18

C#判斷數據類型

2009-09-03 18:55:08

C#判斷瀏覽器
點贊
收藏

51CTO技術棧公眾號