/// <summary> /// This clips the subject polygon against the clip polygon (gets the intersection of the two polygons) /// </summary> public static void GetIntersectedPolygon(StructList <Vector2> subjectPoly, StructList <Vector2> clipPoly, StructList <Vector2> outputList) { if (subjectPoly.size < 3 || clipPoly.size < 3) { throw new ArgumentException(string.Format("The polygons passed in must have at least 3 Vector2s: subject={0}, clip={1}", subjectPoly.size.ToString(), clipPoly.size.ToString())); } outputList.size = 0; outputList.AddRange(subjectPoly); // Make sure it's clockwise if (!IsClockwise(subjectPoly, out bool invalid)) { outputList.Reverse(); } if (invalid) { return; } s_EdgeList = s_EdgeList ?? new StructList <Edge>(); s_InputList = s_InputList ?? new StructList <Vector2>(subjectPoly.size); IterateEdgesClockwise(clipPoly, s_EdgeList); // Walk around the clip polygon clockwise for (int i = 0; i < s_EdgeList.size; i++) { ref Edge clipEdge = ref s_EdgeList.array[i]; s_InputList.size = 0; s_InputList.AddRange(outputList); outputList.size = 0; // Sometimes when the polygons don't intersect, this list goes to zero. Jump out to avoid an index out of range exception if (s_InputList.size == 0) { break; } Vector2 S = s_InputList.array[s_InputList.size - 1]; for (int index = 0; index < s_InputList.size; index++) { ref Vector2 E = ref s_InputList.array[index]; if (IsInside(clipEdge, E)) { if (!IsInside(clipEdge, S)) { Vector2?v = GetIntersect(S, E, clipEdge.from, clipEdge.to); if (v == null) { throw new ApplicationException("Line segments don't intersect"); // may be colinear, or may be a bug } else { outputList.Add(v.Value); } } outputList.Add(E); } else if (IsInside(clipEdge, S)) { Vector2?Vector2 = GetIntersect(S, E, clipEdge.from, clipEdge.to); if (Vector2 == null) { throw new ApplicationException("Line segments don't intersect"); // may be colinear, or may be a bug } else { outputList.Add(Vector2.Value); } } S = E; }