# An example of polygon conflict detection based on c# implementation

Time：2021-10-25

### preface

Previously, I encountered a problem of polygon conflict detection in the project. Through Baidu, Bing and Google, I found that the existing schemes are either incomplete scene coverage or implemented through third-party class libraries (which can hardly be decompiled). However, the use of third-party class libraries is prohibited in the project, so I implemented this algorithm myself.

The scene is like this. There are two polygons, polygon A and polymorph B. It is necessary to judge whether polygon B is within polymorph a, that is, whether polygon B is a sub polygon of polygon a.

1. All points of B are in a
2. All points of a are outside B
3. The line segment of a does not intersect the line segment of B

### Next, implement

Step 1: create a polygon class

``````1 /// <summary>
2 // polygon
3 /// </summary>
4 public class Area_Dto
5 {
6     /// <summary>
7 // collection of points
8     /// </summary>
9     public List<Point_Dto> Points { get; set; }
10     /// <summary>
11 // collection of line segments
12     /// </summary>
13     public List<LineSagement_Dto> LineSagements { get; set; }
14 }

polygon``````

Step 2: create a point class

``````1 /// <summary>
2 // point
3 /// </summary>
4 public class Point_Dto
5 {
6     public Point_Dto(double x, double y)
7     {
8         this.X = x;
9         this.Y = y;
10     }
11     /// <summary>
12 // X coordinate of point
13     /// </summary>
14     public double X { get; private set; }
15     /// <summary>
16 // Y coordinate of point
17     /// </summary>
18     public double Y { get; private set; }
19 }

spot``````

Step 3: create segment class

``````1 /// <summary>
2 // line segment
3 /// </summary>
4 public class LineSagement_Dto
5 {
6     public LineSagement_Dto(Point_Dto start, Point_Dto end)
7     {
8         this.Start = start;
9         this.End = end;
10         GetFuncParam(this);
11     }
12      /// <summary>
13 // starting point of line segment
14      /// </summary>
15      public Point_Dto Start { get; private set; }
16      /// <summary>
17 // end point of line segment
18      /// </summary>
19      public Point_Dto End { get; private set; }
20      /// <summary>
21 // type of line segment
22      /// </summary>
23      public LineType_Enum FunType { get; set; }
24      /// <summary>
25 // only when the line segment is a slash can it have practical effect
26 // slope of line segment and intersection of line segment and Y axis
27      /// </summary>
28      public List<double> Params { get; set; } = new List<double>();
29      /// <summary>
30 // intersection list
31      /// </summary>
32      public List<Point_Dto> Intersection { get; set; } = new List<Point_Dto>();
33
34      /// <summary>
35 // find the slope of the current line segment. When the current line segment is a slash, find the intersection with the Y axis
36      /// </summary>
37      public void GetFuncParam(LineSagement_Dto lineSegment)
38         {
39             double x1 = this.Start.X;
40             double y1 = this.Start.Y;
41             double x2 = this.End.X;
42             double y2 = this.End.Y;
43
44             if (x1 == x2)
45             {
46                 //type=2
47                 this.FunType = LineType_Enum.XX;
49
50             }
51             else if (y1 == y2)
52             {
53                 //type=1
54                 this.FunType = LineType_Enum.YY;
56             }
57             else
58             {
59                 //type=3
60                 this.FunType = LineType_Enum.XnXYnY;
61                 double a = (y2 - y1) / (x2 - x1);// Slope
62                 double b = y1 - (x1 * ((y2 - y1) / (x2 - x1)));// Intersection with y axis
65             }
66
67         }
68 }

line segment``````

Step 4: create type enumeration of line segments

``````/// <summary>
///Type of segment
/// </summary>
public enum LineType_Enum
{
/// <summary>
///Vertical line
/// </summary>
XX,
/// <summary>
///Horizontal line
/// </summary>
YY,
/// <summary>
///Slash
/// </summary>
XnXYnY
}``````

Step 5: add a conflict detection method to the polygon class

``````1 /// <summary>
2 // polygon conflict detection
3 /// </summary>
4 public bool CheckIfInArea(Area_Dto area)
5 {
6     if (area.LineSagements == null)
7     {
8         return true;
9     }
10 // if the child node is outside the parent, it ends
11     foreach (Point_Dto point in this.Points)
12     {
13         if (!point.CheckIfInArea(area))
14             return false;
15     }
16 // if the parent node has a child node, it ends
17     foreach (Point_Dto point in area.Points)
18     {
19         if (point.CheckIfInChildArea(this))
20             return false;
21     }
22 // if all child segments and parent segments do not intersect, there will be no conflict
23     if (WhetherPolygonIntersection(area))
24     {
25         foreach (LineSagement_Dto edg in this.LineSagements)
26         {
27             if (edg.Intersection.Any())
28             {
29                 if (edg.FunType == LineType_Enum.XX)
30                 {
31                     List<Point_Dto> jiaodainList = edg.Intersection.OrderBy(m => m.Y).ToList();
32                     for (int i = 0; i < jiaodainList.Count - 1; i++)
33                     {
34                         Point_Dto start = jiaodainList[i];
35                         Point_Dto end = jiaodainList[i + 1];
36                         Point_Dto z = new Point_Dto(start.X, start.Y + ((end.Y - start.Y) / 2));
37                         if (z.CheckIfInArea(area))
38                         {
39                             continue;
40                         }
41                         else
42                         {
43                             return false;
44                         }
45                     }
46                 }
47                 else if (edg.FunType == LineType_Enum.YY)
48                 {
49                     List<Point_Dto> jiaodainList = edg.Intersection.OrderBy(m => m.X).ToList();
50                     for (int i = 0; i < jiaodainList.Count - 1; i++)
51                     {
52                         Point_Dto start = jiaodainList[i];
53                         Point_Dto end = jiaodainList[i + 1];
54                         Point_Dto z = new Point_Dto(start.X + ((end.X - start.X) / 2), start.Y);
55                         if (z.CheckIfInArea(area))
56                         {
57                             continue;
58                         }
59                         else
60                         {
61                             return false;
62                         }
63                     }
64                 }
65                 else if (edg.FunType == LineType_Enum.XnXYnY)
66                 {
67                     if (edg.Start.Y <= edg.End.Y)
68                     {
69                         List<Point_Dto> jiaodainList = edg.Intersection.OrderBy(m => m.X).ThenBy(m => m.Y).ToList();
70                         for (int i = 0; i < jiaodainList.Count - 1; i++)
71                         {
72                             Point_Dto start = jiaodainList[i];
73                             Point_Dto end = jiaodainList[i + 1];
74                             Point_Dto z = new Point_Dto(start.X + ((end.X - start.X) / 2), start.Y + ((end.Y - start.Y) / 2));
75                             if (z.CheckIfInArea(area))
76                             {
77                                 continue;
78                             }
79                             else
80                             {
81                                 return false;
82                             }
83                         }
84                     }
85                     else
86                     {
87                         List<Point_Dto> jiaodainList = edg.Intersection.OrderBy(m => m.X).ThenByDescending(m => m.Y).ToList();
88                         for (int i = 0; i < jiaodainList.Count - 1; i++)
89                         {
90                             Point_Dto start = jiaodainList[i];
91                             Point_Dto end = jiaodainList[i + 1];
92                             Point_Dto z = new Point_Dto(start.X + ((end.X - start.X) / 2), start.Y - ((start.Y - end.Y) / 2));
93                             if (z.CheckIfInArea(area))
94                             {
95                                 continue;
96                             }
97                             else
98                             {
99                                 return false;
100                             }
101                         }
102                     }
103                 }
104             }
105         }
106     }
107     else
108     {
109         return true;
110     }
111     return true;
112 }

Polygon conflict detection``````

Step 6: add the judgment method of the relationship between point and line segment in the point class

``````1 /// <summary>
2 // does the ray from this point to the right pass through sagement
3 // definition of crossing:
4 // this point is on the vertex of sagement
5 // this point is on sagement
6 // this point does not meet the above two conditions, and the ray from this point passes through sagement
7 /// </summary>
8 /// <param name="sagement"></param>
9 // / < returns > true: passing through line segment false: not passing through line segment < / returns >
10 public PointWithLineSagementState_Enum CheckPointInLineSagement(LineSagement_Dto sagement)
11 {
12     double px = this.X;
13     double py = this.Y;
14     //bool flag = false;
15
16
17     Point_Dto pi = sagement.Start;
18     Point_Dto pj = sagement.End;
19     double sx = pi.X; double sy = pi.Y;
20     double tx = pj.X; double ty = pj.Y;
21
22 // the point coincides with the vertex of the line segment
23     bool psTf = (px == sx && py == sy);
24     bool ptTf = (px == tx && py == ty);
25     if (psTf || ptTf)
26     {
27         return PointWithLineSagementState_Enum.VertexOverlap;
28     }
29     switch (sagement.FunType)
30     {
31         case LineType_Enum.XX:
32             if (px == pi.X && ((py <= sy && py >= ty) || (py >= sy && py <= ty)))
33                 return PointWithLineSagementState_Enum.OnLineSagement;
34             break;
35         case LineType_Enum.YY:
36             if (py == pi.Y && ((px >= sx && px <= tx) || (px <= sx && px >= tx)))
37                 return PointWithLineSagementState_Enum.OnLineSagement;
38             break;
39         case LineType_Enum.XnXYnY:
40         default:
41             break;
42     }
43 // judge whether the endpoint of the line segment is on both sides of the ray
44     if ((sy < py && ty >= py) || (sy >= py && ty < py))
45     {
46 // the X coordinate of the point on the line segment that is the same as the Y coordinate of the ray
47         double x = sx + (py - sy) * (tx - sx) / (ty - sy);
48 // point on line segment
49         if (x == px)
50         {
51             return PointWithLineSagementState_Enum.OnLineSagement;
52         }
53 // ray passing through line segment
54         if (x > px)
55         {
56             return PointWithLineSagementState_Enum.Cross;
57         }
58     }
59     return PointWithLineSagementState_Enum.UnCross;
60 }
61
62 /// <summary>
63 // relationship between dots and lines
64 /// </summary>
65 public enum PointWithLineSagementState_Enum
66 {
67     /// <summary>
68 // vertex coincidence
69     /// </summary>
70     VertexOverlap,
71     /// <summary>
72 // intersection
73     /// </summary>
74     Cross,
75     /// <summary>
76 // disjoint
77     /// </summary>
78     UnCross,
79     /// <summary>
80 // on line segment
81     /// </summary>
82     OnLineSagement
83 }

Judgment of the relationship between points and line segments``````

Step 7: implement the judgment method of whether the points of the sub polygon are in the parent polygon in the point class

``````1 /// <summary>
2 // is the point of the sub polygon within the parent polygon
3 /// </summary>
4 // / < param name = "thearea" > parent polygon < / param >
5 // / < param name = "vertexoverlap" > whether the vertices are included in the graph when they coincide. It is calculated by default < / param >
6 /// <returns></returns>
7 public bool CheckIfInArea(Area_Dto theArea)
8 {
9     int cnt = 0;
10     foreach (LineSagement_Dto lineSagement in theArea.LineSagements)
11     {
12         switch (CheckPointInLineSagement(lineSagement))
13         {
14             case PointWithLineSagementState_Enum.Cross:
15                 cnt += 1;
16                 break;
17             case PointWithLineSagementState_Enum.OnLineSagement:
18                 return true;
19             case PointWithLineSagementState_Enum.VertexOverlap:
20                 return true;
21             case PointWithLineSagementState_Enum.UnCross:
22             default:
23                 break;
24         }
25     }
26 // when the number of times the ray passes through the polygon boundary is odd, the point is in the polygon
27     if (cnt % 2 == 1)
28     {
29         return true;// Point in polygon
30     }
31     else
32     {
33         return false;// The point is not within the polygon
34     }
35 }

Whether the points of the child polygon are within the parent polygon``````

Step 8: implement the judgment method of whether the point of the parent polygon is in the sub polygon in the point class

``````1 /// <summary>
2 // is the point of the parent polygon within the child polygon
3 /// </summary>
4 /// <param name="theArea"></param>
5 /// <returns></returns>
6 public bool CheckIfInChildArea(Area_Dto theArea)
7 {
8     int cnt = 0;
9     foreach (LineSagement_Dto lineSagement in theArea.LineSagements)
10     {
11         switch (CheckPointInLineSagement(lineSagement))
12         {
13             case PointWithLineSagementState_Enum.Cross:
14                 cnt += 1;
15                 break;
16             case PointWithLineSagementState_Enum.OnLineSagement:
17                 return false;
18             case PointWithLineSagementState_Enum.VertexOverlap:
19                 return false;
20             case PointWithLineSagementState_Enum.UnCross:
21             default:
22                 break;
23         }
24     }
25 // when the number of times the ray passes through the polygon boundary is odd, the point is in the polygon
26     if (cnt % 2 == 1)
27     {
28         return true;// Point in polygon
29     }
30     else
31     {
32         return false;// The point is not within the polygon
33     }
34 }

Is the point of the parent polygon within the child polygon``````

Step 9: implement the method of whether the line segment of the polygon itself intersects all the line segments of another polygon in the polygon class

``````1  /// <summary>
2 // does the line segment intersect all the line segments of the polygon
3 // true: Yes
4 // false: no
5 /// </summary>
6 public bool WhetherPolygonIntersection(Area_Dto father)
7 {
8     List<LineSagement_Dto> childEdgeXfatherEdge_List = new List<LineSagement_Dto>();
9     foreach (LineSagement_Dto edg in this.LineSagements)
10     {
11         Point_Dto a = edg.Start;
12         Point_Dto b = edg.End;
13         foreach (LineSagement_Dto fatherEdge in father.LineSagements)
14         {
15             Point_Dto c = fatherEdge.Start;
16             Point_Dto d = fatherEdge.End;
17
18             double denominator = (b.Y - a.Y) * (d.X - c.X) - (a.X - b.X) * (c.Y - d.Y);
19 // if the denominator is 0, it is parallel or collinear and does not intersect
20             if (denominator == 0)
21             {
22 // vertical line
23                 if (edg.FunType == LineType_Enum.XX)
24                 {
25 // collinear
26                     if (edg.Start.X == fatherEdge.Start.X)
27                     {
28 // no overlap
29                         if (b.Y > c.Y || a.Y < d.Y)
30                         {
31                             continue;
32                         }
33 // full overlap
34                         if (a.Y == c.Y && b.Y == d.Y)
35                         {
36                             continue;
37                         }
38 // upper straddle (including two wires connected)
39                         if (a.Y > c.Y && b.Y <= c.Y && b.Y >= d.Y)
40                         {
42                             continue;
43                         }
44 // lower straddle (including two lines connected)
45                         if (a.Y <= c.Y && a.Y >= d.Y && b.Y < d.Y)
46                         {
48                             continue;
49                         }
50 // parent steamed stuffed bun
51                         if (c.Y >= a.Y && d.Y <= b.Y)
52                         {
53                             continue;
54                         }
55 // child package parent
56                         if (a.Y >= c.Y && b.Y <= d.Y)
57                         {
60                             continue;
61                         }
62                     }
63 // parallel
64                     else
65                     {
66                         continue;
67                     }
68                 }
69
70 // horizontal line
71                 else if (edg.FunType == LineType_Enum.YY)
72                 {
73 // collinear
74                     if (edg.Start.Y == fatherEdge.Start.Y)
75                     {
76 // no overlap
77                         if (b.X < c.X || a.X > d.X)
78                         {
79                             continue;
80                         }
81 // full overlap
82                         if (a.X == c.X && b.X == d.X)
83                         {
84                             continue;
85                         }
86 // left straddle (including two lines connected)
87                         if (a.X < c.X && b.X >= c.X && b.X <= d.X)
88                         {
90                             continue;
91                         }
92 // right straddle (including two wires connected)
93                         if (b.X > d.X && a.X >= c.X && a.X <= d.X)
94                         {
96                             continue;
97                         }
98 // parent steamed stuffed bun
99                         if (c.X <= a.X && d.X >= b.X)
100                         {
101                             continue;
102                         }
103 // child package parent
104                         if (a.X <= c.X && b.X >= d.X)
105                         {
108                             continue;
109                         }
110                     }
111 // parallel
112                     else
113                     {
114                         continue;
115                     }
116                 }
117 // slash
118                 else if (edg.FunType == LineType_Enum.XnXYnY)
119                 {
120 // collinear
121                     if (edg.Params.First().Equals(fatherEdge.Params.First()) && edg.Params.Last().Equals(fatherEdge.Params.Last()))
122                     {
123 // no overlap
124                         if ((a.X < c.X && b.X < c.X)
125                             || (a.X > d.X && b.X > d.X))
126                         {
127                             continue;
128                         }
129 // full overlap
130                         if (a.X == c.X && a.Y == c.Y && b.X == d.X && b.Y == d.Y)
131                         {
132                             continue;
133                         }
134 // cross erection (including two-wire connection)
135                         if (a.X < c.X && b.X >= c.X && b.X <= d.X)
136                         {
138                             continue;
139                         }
140 // cross erection (including two-wire connection)
141                         if (a.X >= c.X && a.X <= d.X && b.X > d.X)
142                         {
144                             continue;
145                         }
146 // parent steamed stuffed bun
147                         if (a.X >= c.X && a.X <= d.X && b.X >= c.X && b.X <= d.X)
148                         {
149                             continue;
150                         }
151 // child package parent
152                         if (a.X <= c.X && b.X >= d.X)
153                         {
156                             continue;
157                         }
158                     }
159 // parallel
160                     else
161                     {
162                         continue;
163                     }
164                 }
165             }
166 // intersection coordinates of the line where the line segment is located (x, y)
167             double x = ((b.X - a.X) * (d.X - c.X) * (c.Y - a.Y)
168                 + (b.Y - a.Y) * (d.X - c.X) * a.X
169                 - (d.Y - c.Y) * (b.X - a.X) * c.X) / denominator;
170             double y = -((b.Y - a.Y) * (d.Y - c.Y) * (c.X - a.X)
171                 + (b.X - a.X) * (d.Y - c.Y) * a.Y
172                 - (d.X - c.X) * (b.Y - a.Y) * c.Y) / denominator;
173 // judge whether the intersection is on two line segments
174             if (
175 // intersection on segment 1
176                (x - a.X) * (x - b.X) <= 0 && (y - a.Y) * (y - b.Y) <= 0
177 // and the intersection is also on segment 2
178                && (x - c.X) * (x - d.X) <= 0 && (y - c.Y) * (y - d.Y) <= 0)
179             {
181             }
182             else
183             {
184                 continue;
185             }
186         }
187     }
188     if (this.LineSagements.Where(m => m.Intersection.Any()).Any())
189     {
190         return true;
191     }
192     else
193     {
194         return false;
195     }
196 }

Does the segment intersect all segments of the polygon``````

### summary

This is the end of this article on polygon conflict detection based on c# implementation. For more information on c# polygon conflict detection, please search previous articles of developeppaer or continue to browse the following articles. I hope you will support developeppaer in the future!

## Python data processing in the third stage of employment class

Chapter 1 Introduction to pandas 1.1 / 1.2 jupyter Foundation Create virtual environment a. Create a virtual environment for the specified Python version conda create -nEnvironment variable name python = 3.6 b. Virtual environment command conda env list ——View * * currently owned virtual environments conda remove-N environment variable name — all——delete*Environmental variables activateEnvironment variable […]