/// <summary>Static method to construct the convex hull from an array of points.</summary> /// <remarks> /// Static method to construct the convex hull from an array of points. The /// out_convex_hull array will be populated with the subset of index /// positions which contribute to the convex hull. /// Returns the number of points in the convex hull. /// \param points The points used to create the convex hull. /// \param count The number of points in the input Point2D array. /// \param out_convex_hull An index array allocated by the user at least as big as the size of the input points array. /// </remarks> internal static int Construct(com.epl.geometry.Point2D[] points, int count, int[] out_convex_hull) { com.epl.geometry.ConvexHull convex_hull = new com.epl.geometry.ConvexHull(points, count); int t0 = 0; int tm = 1; com.epl.geometry.Point2D pt_0 = points[t0]; while (tm < count && points[tm].IsEqual(pt_0, com.epl.geometry.NumberUtils.DoubleEps())) { tm++; } // We don't want to close the gap between t0 and tm. convex_hull.m_tree_hull.AddElement(t0, -1); if (tm < count) { convex_hull.m_tree_hull.AddBiggestElement(tm, -1); for (int tp = tm + 1; tp < count; tp++) { // Dynamically insert into the current convex hull. com.epl.geometry.Point2D pt_p = points[tp]; int p = convex_hull.TreeHull_(pt_p); if (p != -1) { convex_hull.m_tree_hull.SetElement(p, tp); } } } // reset the place holder to the point index. // Extracts the convex hull from the tree. Reading the tree in order from first to last is the resulting convex hull. int out_count = 0; for (int i = convex_hull.m_tree_hull.GetFirst(-1); i != -1; i = convex_hull.m_tree_hull.GetNext(i)) { out_convex_hull[out_count++] = convex_hull.m_tree_hull.GetElement(i); } return(out_count); }
internal CallBackPoints(com.epl.geometry.ConvexHull convex_hull) { m_convex_hull = convex_hull; }
internal CallBackStream(com.epl.geometry.ConvexHull convex_hull) { m_convex_hull = convex_hull; }
/// <summary>Static method to construct the convex hull of a Multi_vertex_geometry.</summary> /// <remarks> /// Static method to construct the convex hull of a Multi_vertex_geometry. /// Returns a Geometry. /// \param mvg The geometry used to create the convex hull. /// </remarks> internal static com.epl.geometry.Geometry Construct(com.epl.geometry.MultiVertexGeometry mvg) { if (mvg.IsEmpty()) { return(new com.epl.geometry.Polygon(mvg.GetDescription())); } com.epl.geometry.MultiVertexGeometryImpl mvg_impl = (com.epl.geometry.MultiVertexGeometryImpl)mvg._getImpl(); int N = mvg_impl.GetPointCount(); if (N <= 2) { if (N == 1 || mvg_impl.GetXY(0).Equals(mvg_impl.GetXY(1))) { com.epl.geometry.Point point = new com.epl.geometry.Point(mvg_impl.GetDescription()); mvg_impl.GetPointByVal(0, point); return(point); } else { com.epl.geometry.Point pt = new com.epl.geometry.Point(); com.epl.geometry.Polyline polyline = new com.epl.geometry.Polyline(mvg_impl.GetDescription()); mvg_impl.GetPointByVal(0, pt); polyline.StartPath(pt); mvg_impl.GetPointByVal(1, pt); polyline.LineTo(pt); return(polyline); } } com.epl.geometry.AttributeStreamOfDbl stream = (com.epl.geometry.AttributeStreamOfDbl)mvg_impl.GetAttributeStreamRef(com.epl.geometry.VertexDescription.Semantics.POSITION); com.epl.geometry.ConvexHull convex_hull = new com.epl.geometry.ConvexHull(stream, N); int t0 = 0; int tm = 1; com.epl.geometry.Point2D pt_0 = new com.epl.geometry.Point2D(); com.epl.geometry.Point2D pt_m = new com.epl.geometry.Point2D(); com.epl.geometry.Point2D pt_p = new com.epl.geometry.Point2D(); stream.Read(t0 << 1, pt_0); while (true) { if (tm >= N) { break; } stream.Read(tm << 1, pt_m); if (!pt_m.IsEqual(pt_0, com.epl.geometry.NumberUtils.DoubleEps())) { break; } tm++; } // We don't want to close the gap between t0 and tm. convex_hull.m_tree_hull.AddElement(t0, -1); if (tm < N) { convex_hull.m_tree_hull.AddBiggestElement(tm, -1); for (int tp = tm + 1; tp < mvg_impl.GetPointCount(); tp++) { // Dynamically insert into the current convex hull stream.Read(tp << 1, pt_p); int p = convex_hull.TreeHull_(pt_p); if (p != -1) { convex_hull.m_tree_hull.SetElement(p, tp); } } } // reset the place holder to the point index. // Extracts the convex hull from the tree. Reading the tree in order from first to last is the resulting convex hull. com.epl.geometry.VertexDescription description = mvg_impl.GetDescription(); bool b_has_attributes = (description.GetAttributeCount() > 1); int point_count = convex_hull.m_tree_hull.Size(-1); com.epl.geometry.Geometry hull; if (point_count >= 2) { if (point_count >= 3) { hull = new com.epl.geometry.Polygon(description); } else { hull = new com.epl.geometry.Polyline(description); } com.epl.geometry.MultiPathImpl hull_impl = (com.epl.geometry.MultiPathImpl)hull._getImpl(); hull_impl.AddPath((com.epl.geometry.Point2D[])null, 0, true); com.epl.geometry.Point point = null; if (b_has_attributes) { point = new com.epl.geometry.Point(); } for (int i = convex_hull.m_tree_hull.GetFirst(-1); i != -1; i = convex_hull.m_tree_hull.GetNext(i)) { if (b_has_attributes) { mvg_impl.GetPointByVal(convex_hull.m_tree_hull.GetElement(i), point); hull_impl.InsertPoint(0, -1, point); } else { stream.Read(convex_hull.m_tree_hull.GetElement(i) << 1, pt_p); hull_impl.InsertPoint(0, -1, pt_p); } } } else { System.Diagnostics.Debug.Assert((point_count == 1)); if (b_has_attributes) { com.epl.geometry.Point point = new com.epl.geometry.Point(description); mvg_impl.GetPointByVal(convex_hull.m_tree_hull.GetElement(convex_hull.m_tree_hull.GetFirst(-1)), point); hull = point; } else { stream.Read(convex_hull.m_tree_hull.GetElement(convex_hull.m_tree_hull.GetFirst(-1)) << 1, pt_p); hull = new com.epl.geometry.Point(pt_p); } } return(hull); }