/// <summary> /// Dirty method O(n^2) /// </summary> /// <param name="a_poly1"></param> /// <param name="a_poly2"></param> /// <returns></returns> public static Polygon2D IntersectConvex(Polygon2D a_poly1, Polygon2D a_poly2) { if (!(a_poly1.IsConvex())) { throw new GeomException("Method not defined for nonconvex polygons" + a_poly1); } if (!(a_poly2.IsConvex())) { throw new GeomException("Method not defined for nonconvex polygons" + a_poly2); } // obtain vertices that lie inside both polygons var resultVertices = a_poly1.Vertices .Where(v => a_poly2.ContainsInside(v)) .Concat(a_poly2.Vertices.Where(v => a_poly1.ContainsInside(v))) .ToList(); // add intersections between two polygon segments resultVertices.AddRange(a_poly1.Segments.SelectMany(seg => seg.Intersect(a_poly2.Segments))); // remove any duplicates resultVertices = resultVertices.Distinct().ToList(); // retrieve convex hull of relevant vertices if (resultVertices.Count() >= 3) { var poly = ConvexHull.ComputeConvexHull(resultVertices); Debug.Assert(poly.IsConvex()); return(poly); } return(null); }
/// <summary> /// Looking for K-gon with maximum area /// </summary> /// <param name="a_points"></param> public static Polygon2D ComputeMaximumAreaKgon(IEnumerable <Vector2> a_vertices, int pointLimit) { var oldvertices = a_vertices.Distinct(); var vertices = ConvexHull.ComputeConvexHull(oldvertices).Vertices.ToList(); var x0 = vertices[0].x; var y0 = vertices[0].y; foreach (var vertex in vertices) { if (vertex.x < x0) { x0 = vertex.x; } if (vertex.y < y0) { y0 = vertex.y; } } vertices.Sort((x, y) => ((x.x - x0) * (y.y - y0) - (x.y - y0) * (y.x - x0)).CompareTo(0)); float[,,] f = new float [vertices.Count, vertices.Count, pointLimit]; int[,,] g = new int [vertices.Count, vertices.Count, pointLimit]; for (var i = 0; i < vertices.Count; i++) { for (var j = 0; j < vertices.Count; j++) { for (var k = 0; k < pointLimit; k++) { f[i, j, k] = 0f; } } } for (var plimit = 3; plimit <= pointLimit; plimit++) { var limit = plimit - 3; for (var startPoint = 0; startPoint < vertices.Count; startPoint++) { for (var oldEndPoint = startPoint + 1; oldEndPoint < vertices.Count; oldEndPoint++) { for (var newEndPoint = oldEndPoint + 1; newEndPoint < vertices.Count; newEndPoint++) { float total; if (plimit == 3) { total = TriangleArea(vertices[startPoint], vertices[oldEndPoint], vertices[newEndPoint]); } else { total = f[startPoint, oldEndPoint, limit - 1] + TriangleArea(vertices[startPoint], vertices[oldEndPoint], vertices[newEndPoint]); } if (total > f[startPoint, newEndPoint, limit]) { f[startPoint, newEndPoint, limit] = total; g[startPoint, newEndPoint, limit] = oldEndPoint; } } } } } var optStart = 0; var optEnd = 0; float optArea = 0; for (var startPoint = 0; startPoint < vertices.Count; startPoint++) { for (var endPoint = startPoint + 2; endPoint < vertices.Count; endPoint++) { if (f[startPoint, endPoint, pointLimit - 3] > optArea) { optArea = f[startPoint, endPoint, pointLimit - 3]; optStart = startPoint; optEnd = endPoint; } } } Polygon2D m_optimalSolution = new Polygon2D(); m_optimalSolution.AddVertex(vertices[optStart]); m_optimalSolution.AddVertex(vertices[optEnd]); for (var cnt = pointLimit - 3; cnt >= 0; cnt--) { m_optimalSolution.AddVertex(vertices[g[optStart, optEnd, cnt]]); optEnd = g[optStart, optEnd, cnt]; } return(m_optimalSolution); }
/// <summary> /// Looking for K-gon with maximum point number /// </summary> /// <param name="a_points"></param> public static Polygon2D ComputeMaximumPointsKgon(IEnumerable <Vector2> a_vertices, int pointLimit) { var oldvertices = a_vertices.Distinct(); var vertices = oldvertices.ToList(); var x0 = vertices[0].x; var y0 = vertices[0].y; foreach (var vertex in vertices) { if (vertex.x < x0) { x0 = vertex.x; } if (vertex.y < y0) { y0 = vertex.y; } } vertices.Sort((x, y) => ((x.x - x0) * (y.y - y0) - (x.y - y0) * (y.x - x0)).CompareTo(0)); int [,,] f = new int [vertices.Count, vertices.Count, pointLimit]; int [,,] g = new int [vertices.Count, vertices.Count, pointLimit]; Polygon2D [,,] h = new Polygon2D [vertices.Count, vertices.Count, pointLimit]; for (var i = 0; i < vertices.Count; i++) { for (var j = 0; j < vertices.Count; j++) { for (var k = 0; k < pointLimit; k++) { f[i, j, k] = 0; } } } for (var plimit = 3; plimit <= pointLimit; plimit++) { var limit = plimit - 3; for (var startPoint = 0; startPoint < vertices.Count; startPoint++) { for (var oldEndPoint = startPoint + limit + 1; oldEndPoint < vertices.Count; oldEndPoint++) { for (var newEndPoint = oldEndPoint + 1; newEndPoint < vertices.Count; newEndPoint++) { Polygon2D newgon = new Polygon2D(); if (plimit <= 3) { newgon.AddVertex(vertices[startPoint]); newgon.AddVertex(vertices[oldEndPoint]); } else { foreach (var v in h[startPoint, oldEndPoint, limit - 1].Vertices) { newgon.AddVertex(v); } } newgon.AddVertex(vertices[newEndPoint]); newgon = ConvexHull.ComputeConvexHull(newgon); int tot = PolygonPoints(vertices, newgon); if (tot >= f[startPoint, newEndPoint, limit]) { f[startPoint, newEndPoint, limit] = tot; h[startPoint, newEndPoint, limit] = newgon; } /*int total = 0; * if (plimit == 3) * { * total = 3 + TrianglePoints(vertices, startPoint, oldEndPoint, newEndPoint); * } * else * { * total = f[startPoint, oldEndPoint, limit - 1] + 1 + TrianglePoints(vertices, startPoint, oldEndPoint, newEndPoint); * } * * Debug.Log("Total: " + total); * * if (total > f[startPoint, newEndPoint, limit]) * { * f[startPoint, newEndPoint, limit] = total; * g[startPoint, newEndPoint, limit] = oldEndPoint; * } */ } } } } var optStart = 0; var optEnd = 0; int optNumber = 0; for (var startPoint = 0; startPoint < vertices.Count; startPoint++) { for (var endPoint = startPoint + 2; endPoint < vertices.Count; endPoint++) { if (f[startPoint, endPoint, pointLimit - 3] > optNumber) { optNumber = f[startPoint, endPoint, pointLimit - 3]; optStart = startPoint; optEnd = endPoint; } } } Debug.Log(optNumber); Polygon2D m_optimalSolution = new Polygon2D(); m_optimalSolution = h[optStart, optEnd, pointLimit - 3]; m_optimalSolution.SetPointNumber(optNumber); /*m_optimalSolution.AddVertex(vertices[optStart]); * m_optimalSolution.AddVertex(vertices[optEnd]); * * for (var cnt = pointLimit - 3; cnt >= 0; cnt--) * { * Debug.Log("ggggg:" + TrianglePoints(vertices, optStart, optEnd, g[optStart, optEnd, cnt])); * m_optimalSolution.AddVertex(vertices[g[optStart, optEnd, cnt]]); * optEnd = g[optStart, optEnd, cnt]; * } * * Debug.Log("Optimal Vertices: " + m_optimalSolution.Vertices); */ return(m_optimalSolution); }