/*! Print the given envelope diagram. */ void print_diagram (const Diagram_1& diag) { Diagram_1::Edge_const_handle e = diag.leftmost(); Diagram_1::Vertex_const_handle v; while (e != diag.rightmost()) { std::cout << "Edge: "; if (! e->is_empty()) { Circle_2 circ = e->curve().supporting_circle(); std::cout << " (x - " << CGAL::to_double(circ.center().x()) << ")^2 +" << " (y - " << CGAL::to_double(circ.center().y()) << ")^2 = " << CGAL::to_double(circ.squared_radius()) << std::endl; } else std::cout << " [empty]" << std::endl; v = e->right(); std::cout << "Vertex (" << CGAL::to_double(v->point().x()) << ' ' << CGAL::to_double(v->point().y()) << ')' << std::endl; e = v->right(); } CGAL_assertion (e->is_empty()); std::cout << "Edge: [empty]" << std::endl; return; }
int main (int argc, char* argv[]) { // Read the points from the input file. const char* filename = (argc > 1) ? argv[1] : "ch_points.dat"; std::ifstream in_file(filename); if (!in_file.is_open()) { std::cerr << "Failed to open " << filename << " ..." << std::endl; return -1; } // Read the points from the file, and construct their dual lines. std::list<Dual_line_2> dual_lines; unsigned int n; in_file >> n; std::vector<Point_2> points; points.resize(n); for (unsigned int k = 0; k < n; ++k) { int px, py; in_file >> px >> py; points[k] = Point_2 (px, py); // The line dual to the point (p_x, p_y) is y = p_x*x - p_y, // or: p_x*x - y - p_y = 0: Line_2 line = Line_2 (Number_type(px), Number_type(-1), Number_type(-py)); // Generate the x-monotone curve based on the line and the point index. dual_lines.push_back (Dual_line_2 (line, k)); } in_file.close(); // Compute the lower envelope of dual lines, which corresponds to the upper // part of the convex hull, and their upper envelope, which corresponds to // the lower part of the convex hull. Diagram_1 min_diag; Diagram_1 max_diag; lower_envelope_x_monotone_2(dual_lines.begin(), dual_lines.end(), min_diag); upper_envelope_x_monotone_2(dual_lines.begin(), dual_lines.end(), max_diag); // Output the points along the boundary convex hull in counterclockwise // order. We start by traversing the minimization diagram from left to // right, then the maximization diagram from right to left. std::cout << "The convex hull of " << points.size() << " input points:"; Diagram_1::Edge_const_handle e = min_diag.leftmost(); while (e != min_diag.rightmost()) { std::cout << " (" << points[e->curve().data()] << ')'; e = e->right()->right(); } // Handle the degenerate case of a vertical convex hull edge: if (e->curve().data() != max_diag.leftmost()->curve().data()) std::cout << " (" << points[e->curve().data()] << ')'; e = max_diag.leftmost(); while (e != max_diag.rightmost()) { std::cout << " (" << points[e->curve().data()] << ')'; e = e->right()->right(); } std::cout << std::endl; return 0; }