public void DrawPolygon(Polygon polygon) { List<MeshNode> cornerNodes = polygon.GetRectCorners(); List<Vector2> cornerVectors = new List<Vector2>(); for (int i = 0; i < 4; i++) { cornerVectors.Add(ToScreenCoords(cornerNodes[i].mVector)); } for (int i = 0; i <= 1; i++) { CodeTest.DrawLine(cornerVectors[i], cornerVectors[i + 2], 1, Color.Purple); } foreach (Edge e in polygon.GetEdges()) { if (e.GetContrahent() == null) DrawSingleEdge(e); else DrawEdge(e); } foreach (MeshNode node in polygon.GetNodes()) { DrawNode(node); } }
/// <summary> /// Adds a polygon to the mesh. /// </summary> public void AddPolygon(Polygon toAdd) { Debug.Assert(toAdd.GetEdges() != null); int[] indexes = GetCoveredSectorIndexes(toAdd); for (int y = indexes[1]; y <= indexes[3]; y++) for (int x = indexes[0]; x <= indexes[2]; x++ ) { Debug.Assert(!mSectors[x, y].Contains(toAdd)); mSectors[x,y].Add(toAdd); } }
/// <summary> /// If existant, returns the first common edge to the given polygon, else null. /// Result is a List of two edges: first edge belongs to this polygon, /// second edge belongs to given polygon2. Both are equivalent, e.g. are the /// "one" common edge. /// </summary> /// <param name="polygon2"></param> /// <returns></returns> private List<Edge> GetFirstIncidentEdge(Polygon polygon2) { Debug.Assert(mEdges != null); Debug.Assert(polygon2.GetEdges() != null); Debug.Assert(IsConcave(mEdges)); Debug.Assert(IsConcave(polygon2.mEdges)); bool edgesFound = false; List<Edge> commonEdges = null; List<Edge> edges2 = polygon2.GetEdges(); // find the first common edge of both: foreach (Edge edge in mEdges) { Debug.Assert(edge.mPolyOwners.Count == 1); foreach (Edge edge2 in edges2) { if (edge.RecursiveReverse(edge2)) { if (!edgesFound) { commonEdges = new List<Edge> { edge, edge2 }; edgesFound = true; // return commonEdges; } else { Debug.Assert(IsConcave(mEdges)); Debug.Assert(IsConcave(polygon2.mEdges)); throw new Exception("Polygon.GetFirstIncidentEdges() found too many results!"); } } } } return commonEdges; }
/// <summary> /// Returns a new polygon instance that is the union of this /// and the given polygon. Union is at the first common edge found. /// Returns null if no common edge found. /// </summary> /// <param name="polygon2">the polygon with which to unite</param> /// <param name="commonEdge">returns this polygon's edge that reversely equals /// commonEdge2 from polygon2</param> /// <param name="commonEdge2">returns polygon2's edge that reversely equals /// commonEdge from this polygon</param> /// <returns>united polygon if possible, else null</returns> public List<Edge> GetUnion(Polygon polygon2, out Edge commonEdge, out Edge commonEdge2) { List<Edge> commonEdges = GetFirstIncidentEdge(polygon2); if (commonEdges == null) { commonEdge = null; commonEdge2 = null; return null; } commonEdge = commonEdges[0]; int commonEdgeIndex = mEdges.IndexOf(commonEdge); commonEdge2 = commonEdges[1]; List<Edge> edges2 = polygon2.GetEdges(); int edge2Index = edges2.IndexOf(commonEdge2); List<Edge> newEdges = new List<Edge>(); // copy from mEdges up to the index of edge: int length = mEdges.Count; for (int i = 0; i < commonEdgeIndex; i++) { Debug.Assert(mEdges[i].mEndNode == mEdges[i+1].mStartNode); newEdges.Add(mEdges[i]); } // copy along edges2 from and to edge2Index int length2 = edges2.Count; int j = (edge2Index + 1) % length2; if (commonEdgeIndex > 0) Debug.Assert(mEdges[commonEdgeIndex-1].mEndNode == edges2[j].mStartNode); while (edges2[j] != commonEdge2) { Debug.Assert(edges2[j].mEndNode == edges2[(j+1)%length2].mStartNode); newEdges.Add(edges2[j]); j = (j + 1) % length2; } Debug.Assert(j == edge2Index); j--; if (j < 0) j = j + length2; if (commonEdgeIndex+1<length) Debug.Assert(edges2[j].mEndNode == mEdges[commonEdgeIndex + 1].mStartNode); // now we're again in mEdges of the first polygon, copy the rest: for (int h = commonEdgeIndex + 1; h < length; h++) { Debug.Assert(mEdges[h].mEndNode == mEdges[(h+1)%length].mStartNode); newEdges.Add(mEdges[h]); } Debug.Assert(AllEdgesIncident(newEdges)); // newEdges finished return newEdges; }
public int CountIncidentEdges(Polygon polygon2) { int counter = 0; List<Edge> edges2 = polygon2.GetEdges(); foreach (Edge edge in mEdges) { foreach (Edge edge2 in edges2) { if (edge.RecursiveReverse(edge2)) { counter++; } } } return counter; }
private static void PolygonTests() { double pi = Math.PI; List<MeshNode> nodes = new List<MeshNode> { new MeshNode(0, 0), new MeshNode(10, 0), new MeshNode(10, 10), new MeshNode(0, 10) }; Polygon polygon = new Polygon(nodes); polygon.ImposeOwnership(); List<Edge> edges = polygon.GetEdges(); Debug.Assert(HelperMethods.Circa( HelperMethods.GetAngleDifference(edges[0].ToVector(), edges[1].ToVector()), pi / 2)); Debug.Assert(Polygon.IsConcave(polygon.GetEdges()), "CodeTest.PolygonTests(): Polygon not concave!"); Debug.Assert(polygon.PointInPolygon(new Vector2(10, 5), false), "CodeTest.PolygonTests(): 10,5 not in Polygon!"); Random r = new Random(); Vector2 point1 = new Vector2((float)(10 * r.NextDouble()), (float)(10 * r.NextDouble())); Debug.Assert(polygon.PointInPolygon(point1, false), "CodeTest.PolygonTests(): Random point not in Polygon!"); Vector2 p1 = new Vector2(0, 0); Vector2 p2 = new Vector2(0, 10); Vector2 p3 = new Vector2(10, 0); Vector2 p4 = new Vector2(10, 10); Debug.Assert(polygon.PointInPolygon(p1, false), "PointInPolygon Test failed!"); Debug.Assert(polygon.PointInPolygon(p2, false), "PointInPolygon Test failed!"); Debug.Assert(polygon.PointInPolygon(p3, false), "PointInPolygon Test failed!"); Debug.Assert(polygon.PointInPolygon(p4, false), "PointInPolygon Test failed!"); List<MeshNode> nodes2 = new List<MeshNode> { nodes[1], new MeshNode(20, 0), new MeshNode(20, 10), nodes[2] }; Polygon polygon2 = new Polygon(nodes2); polygon2.ImposeOwnership(); List<Polygon> polygonNeighbours = polygon.GetAdjacentPolygons(); List<Polygon> polygon2Neighbours = polygon2.GetAdjacentPolygons(); Debug.Assert(polygonNeighbours.Count == 1 && polygonNeighbours.Contains(polygon2)); Debug.Assert(polygon2Neighbours.Count == 1 && polygon2Neighbours.Contains(polygon)); Edge commonEdge, commonEdge2; List<Edge> unitedEdges = polygon.GetUnion(polygon2, out commonEdge, out commonEdge2); Polygon unitedPolygon = new Polygon(unitedEdges); unitedPolygon.ImposeOwnership(); polygon.Delete(true); polygon2.Delete(true); unitedPolygon.CleanUp(true); Debug.Assert(commonEdge.mStartNode == null); Debug.Assert(commonEdge.mEndNode == null); Debug.Assert(commonEdge2.mStartNode == null); Debug.Assert(commonEdge2.mEndNode == null); Debug.Assert(unitedPolygon.EdgesHaveOneOwner()); Debug.Assert(unitedPolygon.NodesEdgesOwnerTest()); Debug.WriteLine("Use breakpoint to check the last union test."); Debug.WriteLine("Polygon tests done."); unitedPolygon.Delete(true); }