/** Finds the minimum bounding area containing all points in <param name="points">points</param>, * where the face of each point faces <param name="center">center</param>. */ private List<Vector3> facePointArea(List<Vector3> points, Vector3 center) { List<WaterEdge> edges = new List<WaterEdge>(); for (int i = 0; i < points.Count; i++ ) { edges.Add(new WaterEdge(points[i], points[(i+1)%points.Count], new List<Vector3>())); } for (int i = 0; i < edges.Count; i++) { if (!edgeFacesPoint(edges[i], center)) { //for the other winding order //int prev = (i + edges.Count - 1) % edges.Count; //edges[prev] = new WaterEdge(edges[prev].NodeA, edges[i].NodeB, new List<Vector3>()); //edges.RemoveAt(i); //i = (i + edges.Count - 2) % edges.Count; //i -= 2; //if (i < 0) i = 0; int next = (i + 1) % edges.Count; edges[i] = new WaterEdge(edges[i].NodeA, edges[next].NodeB, new List<Vector3>()); edges.RemoveAt(next); i--; } } List<Vector3> boundPoits = new List<Vector3>(edges.Count); for (int i = 0; i < edges.Count; i++) { boundPoits.Add(edges[i].NodeA); } return boundPoits; }
/** Finds the minimum bounding convex area containing all points in <param name="points">points</param>. */ /* NOTE: only works if xMin, xMax, yMin and yMax are unique! */ private List<Vector3> minimumConvexArea(List<Vector3> points, List<Vector3> initialPoints, Vector3 center) { List<Vector3> distSortedPoints = new List<Vector3>(points); distSortedPoints.Sort( delegate(Vector3 v1, Vector3 v2) { return (int) (Vector3.DistanceSquared(center, v1) - Vector3.DistanceSquared(center, v2)); } ); List<WaterEdge> bounds = new List<WaterEdge>(); for (int i = 0; i < initialPoints.Count; i++) { int next = (i + 1) % initialPoints.Count; bounds.Add(new WaterEdge(initialPoints[i], initialPoints[next], isClosed(points, center, initialPoints[i], initialPoints[next]))); } int nextSort = 0; int firstOpen = 0; while (firstOpen < bounds.Count) { Vector3 next = distSortedPoints[nextSort++]; for (int i = firstOpen; i < bounds.Count; i++) { if (bounds[i].isOutside(next)) { WaterEdge edgeA = new WaterEdge(bounds[i].NodeA, next, isClosed(points, center, bounds[i].NodeA, next)); WaterEdge edgeB = new WaterEdge(next, bounds[i].NodeB, isClosed(points, center, next, bounds[i].NodeB)); bounds.Remove(bounds[i]); bounds.Insert(i, edgeB); bounds.Insert(i, edgeA); if (i == firstOpen) { while (firstOpen < bounds.Count && !bounds[firstOpen].Closed) firstOpen++; } break; } } } List<Vector3> boundPoits = new List<Vector3>(bounds.Count); for (int i = 0; i < bounds.Count; i++) { boundPoits.Add(bounds[i].NodeA); } return boundPoits; }
private bool edgeFacesPoint(WaterEdge edge, Vector3 point) { Vector2 n = Vector2.Normalize(new Vector2(edge.NodeA.X - edge.NodeB.X, edge.NodeA.Y - edge.NodeB.Y)); Vector2 v = new Vector2(point.X - edge.NodeA.X, point.Y - edge.NodeA.Y); float dist = Vector2.Dot(new Vector2(-n.Y, n.X), v); //if (dist <= 0) Console.WriteLine("No Face!"); return (dist > 0); }