int main() { std::vector<Point_3> points; CGAL::Object ch_object; Traits ch_traits; std::cout << "Testing hull of no points " << std::endl; CGAL::convex_hull_3(points.begin(), points.end(), ch_object, ch_traits); assert(ch_object.is_empty()); Point_3 p1(0, 0, 0); points.push_back(p1); std::cout << "Testing hull of one point " << std::endl; CGAL::convex_hull_3(points.begin(), points.end(), ch_object, ch_traits); Point_3 ch_point; assert(CGAL::assign(ch_point, ch_object)); std::cout << "Testing hull of two points " << std::endl; Point_3 p2(1, 0, 0); points.push_back(p2); CGAL::convex_hull_3(points.begin(), points.end(), ch_object, ch_traits); Segment_3 ch_segment; assert(CGAL::assign(ch_segment, ch_object)); std::cout << "Testing hull of three points " << std::endl; Point_3 p3(1, 1, 0); points.push_back(p3); CGAL::convex_hull_3(points.begin(), points.end(), ch_object, ch_traits); Triangle_3 ch_triangle; assert(CGAL::assign(ch_triangle, ch_object)); std::cout << "Testing hull of four points " << std::endl; Point_3 p4(1, 1, 1); points.push_back(p4); CGAL::convex_hull_3(points.begin(), points.end(), ch_object, ch_traits); Polyhedron_3 poly; assert(CGAL::assign(poly, ch_object)); assert(poly.size_of_vertices()==4); std::cout << "Testing hull of collinear points " << std::endl; test_collinear(); std::cout << "Testing hull of points in xy-plane " << std::endl; test_coplanar_xy(); std::cout << "Testing hull of points in xz-plane " << std::endl; test_coplanar_xz(); std::cout << "Testing hull of points in yz-plane " << std::endl; test_coplanar_yz(); std::cout << "Testing hull of points in arbitrary plane " << std::endl; test_coplanar_arbitrary(); std::cout << "Testing hull of points in arbitrary plane " << std::endl; test_coplanar_arbitrary(); std::cout << "Testing hull of coplanar points which convex hull is a triangle " << std::endl; test_coplanar_triangle(); return 0; }
static Point_3 getCenter(const Polyhedron_3 &p) { Point_3 C(0., 0., 0.); for (auto I = p.vertices_begin(), E = p.vertices_end(); I != E; ++I) C = C + (I->point() - CGAL::Origin()); C = C * (1. / p.size_of_vertices()); return C; }
void CGALConvexHull3D::run(const MatrixFr& points) { std::list<Point_3> cgal_pts; const size_t num_pts = points.rows(); const size_t dim = points.cols(); if (dim != 3) { std::stringstream err_msg; err_msg << "Invalid dim: " << dim << " Expect dim=3."; throw RuntimeError(err_msg.str()); } for (size_t i=0; i<num_pts; i++) { const VectorF& p = points.row(i); cgal_pts.push_back(Point_3(p[0], p[1], p[2])); } Polyhedron_3 hull; CGAL::convex_hull_3(cgal_pts.begin(), cgal_pts.end(), hull); assert(hull.is_closed()); assert(hull.is_pure_triangle()); const size_t num_vertices = hull.size_of_vertices(); const size_t num_faces = hull.size_of_facets(); m_vertices.resize(num_vertices, dim); m_faces.resize(num_faces, 3); size_t vertex_count=0; for (auto itr=hull.vertices_begin(); itr!=hull.vertices_end(); itr++) { const Point_3& p = itr->point(); m_vertices.coeffRef(vertex_count, 0) = p.x(); m_vertices.coeffRef(vertex_count, 1) = p.y(); m_vertices.coeffRef(vertex_count, 2) = p.z(); itr->id() = vertex_count; vertex_count++; } size_t face_count=0; for (auto f_itr=hull.facets_begin(); f_itr!=hull.facets_end(); f_itr++) { size_t edge_count=0; auto h_itr = f_itr->facet_begin(); do { m_faces.coeffRef(face_count, edge_count) = h_itr->vertex()->id(); edge_count++; h_itr++; } while (h_itr != f_itr->facet_begin()); face_count++; } compute_index_map(points); reorient_faces(); }
int main() { CGAL::Random_points_in_sphere_3<Point_3, PointCreator> gen(100.0); // generate 250 points randomly on a sphere of radius 100.0 // and copy them to a vector std::vector<Point_3> points; CGAL::cpp11::copy_n( gen, 250, std::back_inserter(points) ); // define polyhedron to hold convex hull Polyhedron_3 poly; // compute convex hull of non-collinear points CGAL::convex_hull_3(points.begin(), points.end(), poly); std::cout << "The convex hull contains " << poly.size_of_vertices() << " vertices" << std::endl; // assign a plane equation to each polyhedron facet using functor Plane_from_facet std::transform( poly.facets_begin(), poly.facets_end(), poly.planes_begin(),Plane_from_facet()); return 0; }
int main() { CGAL::Random_points_in_sphere_3<Point_3> gen(100.0); std::list<Point_3> points; // generate 250 points randomly on a sphere of radius 100.0 // and insert them into the triangulation CGAL::cpp0x::copy_n(gen, 250, std::back_inserter(points) ); Delaunay T; T.insert(points.begin(), points.end()); std::list<Vertex_handle> vertices; T.incident_vertices(T.infinite_vertex(), std::back_inserter(vertices)); std::cout << "This convex hull of the 250 points has " << vertices.size() << " points on it." << std::endl; // remove 25 of the input points std::list<Vertex_handle>::iterator v_set_it = vertices.begin(); for (int i = 0; i < 25; i++) { T.remove(*v_set_it); v_set_it++; } //copy the convex hull of points into a polyhedron and use it //to get the number of points on the convex hull Polyhedron_3 chull; CGAL::convex_hull_3_to_polyhedron_3(T,chull); std::cout << "After removal of 25 points, there are " << chull.size_of_vertices() << " points on the convex hull." << std::endl; return 0; }
/** * Performs the testing of dynamic convex hull of CGAL. */ int main(int argc, char** argv) { DEBUG_START; if (argc != 2) { print_usage(argc, argv); DEBUG_END; return EXIT_FAILURE; } int num_points = 0; if (sscanf(argv[1], "%d", &num_points) != 1) { print_usage(argc, argv); DEBUG_END; return EXIT_FAILURE; } CGAL::Random_points_on_sphere_3<Point_3> gen(100.0); std::list<Point_3> points; /* * generate <num_points> points randomly on a sphere of radius 100.0 * and copy them to a std::vector */ CGAL::cpp11::copy_n(gen, num_points, std::back_inserter(points) ); /* begin time measurement */ TimeMeasurer timer; timer.pushTimer(); Delaunay T; T.insert(points.begin(), points.end()); std::list<Vertex_handle> vertices; T.incident_vertices(T.infinite_vertex(), std::back_inserter(vertices)); /* * copy the convex hull of points into a polyhedron and use it * to get the number of points on the convex hull */ Polyhedron_3 chull0; CGAL::convex_hull_3_to_polyhedron_3(T,chull0); std::cout << "The convex hull contains " << chull0.size_of_vertices() << " vertices" << std::endl; /* end time measurement */ double timeFirst = timer.popTimer(); printf("Time for initial construction of convex hull: %lf\n", timeFirst); /* begin time measurement */ timer.pushTimer(); /* Remove 90% of points. */ float nReduced = (1. - 1. / (float) FACTOR_OF_VERTICES_REDUCTION) * chull0.size_of_vertices(); std::list<Vertex_handle>::iterator v_set_it = vertices.begin(); for (int i = 0; i < nReduced; i++) { T.remove(*v_set_it); v_set_it++; } /* * copy the convex hull of points into a polyhedron and use it * to get the number of points on the convex hull */ Polyhedron_3 chull; CGAL::convex_hull_3_to_polyhedron_3(T,chull); /* end time measurement */ double timeSecond = timer.popTimer(); printf("Time for recalculating of convex hull: %lf\n", timeSecond); std::cout << "The convex hull contains " << chull.size_of_vertices() << " vertices" << std::endl; DEBUG_END; return 0; }
/* FIXME: Copied from Polyhedron_io.cpp with slight modifications. */ static std::shared_ptr<Polyhedron> convertWithAssociation(Polyhedron_3 p, const Point_3 &C, const std::vector<Plane_3> &initPlanes) { /* Check for non-emptiness. */ ASSERT(p.size_of_vertices()); ASSERT(p.size_of_facets()); int numVertices = p.size_of_vertices(); int numFacets = p.size_of_facets(); /* Allocate memory for arrays. */ Vector3d *vertices = new Vector3d[numVertices]; Facet *facets = new Facet[numFacets]; /* Transform vertexes. */ int iVertex = 0; for (auto vertex = p.vertices_begin(); vertex != p.vertices_end(); ++vertex) { Point_3 point = C + vertex->point(); vertices[iVertex++] = Vector3d(point.x(), point.y(), point.z()); } /* * Transform facets. * This algorithm is based on example kindly provided at CGAL online user * manual. See example Polyhedron/polyhedron_prog_off.cpp */ int iFacet = 0; auto plane = p.planes_begin(); auto facet = p.facets_begin(); /* Iterate through the std::lists of planes and facets. */ do { int id = p.indexPlanes_[iFacet]; facets[id].id = id; /* Transform current plane. */ Plane_3 pi = centerizePlane(*plane, Point_3(-C.x(), -C.y(), -C.z()), signedDist(initPlanes[id], C)); facets[id].plane = Plane(Vector3d(pi.a(), pi.b(), pi.c()), pi.d()); /* * Iterate through the std::list of halfedges incident to the curent CGAL * facet. */ auto halfedge = facet->facet_begin(); /* Facets in polyhedral surfaces are at least triangles. */ CGAL_assertion(CGAL::circulator_size(halfedge) >= 3); facets[id].numVertices = CGAL::circulator_size(halfedge); facets[id].indVertices = new int[3 * facets[id].numVertices + 1]; /* * TODO: It's too unsafe architecture if we do such things as setting * the size of internal array outside the API functions. Moreover, it * can cause us to write memory leaks. * indFacets and numFacets should no be public members. */ int iFacetVertex = 0; do { facets[id].indVertices[iFacetVertex++] = std::distance(p.vertices_begin(), halfedge->vertex()); } while (++halfedge != facet->facet_begin()); /* Add cycling vertex to avoid assertion during printing. */ facets[id].indVertices[facets[id].numVertices] = facets[id].indVertices[0]; ASSERT(facets[id].correctPlane()); /* Increment the ID of facet. */ ++iFacet; } while (++plane != p.planes_end() && ++facet != p.facets_end()); return std::make_shared<Polyhedron>(numVertices, numFacets, vertices, facets); }