Example #1
0
int main ()
{
  // Construct an arrangement of four polylines named A--D.
  Arrangement_2    arr;

  Point_2          points1[5] = {Point_2(0,0), Point_2(2,4), Point_2(3,3),
                                 Point_2(4,4), Point_2(6,0)};
  insert (arr, Curve_2 (Polyline_2 (points1, points1 + 5), "A"));

  Point_2          points2[3] = {Point_2(1,5), Point_2(3,3), Point_2(5,5)};
  insert (arr, Curve_2 (Polyline_2 (points2, points2 + 3), "B"));

  Point_2          points3[4] = {Point_2(1,0), Point_2(2,2),
                                 Point_2(4,2), Point_2(5,0)};
  insert (arr, Curve_2 (Polyline_2 (points3, points3 + 4), "C"));

  Point_2          points4[2] = {Point_2(0,2), Point_2(6,2)};
  insert (arr, Curve_2 (Polyline_2 (points4, points4 + 2), "D"));

  // Print all edges that correspond to an overlapping polyline.
  Arrangement_2::Edge_iterator    eit;

  for (eit = arr.edges_begin(); eit != arr.edges_end(); ++eit) {
    if (eit->curve().data().length() > 1) {
      std::cout << "[" << eit->curve() << "]  "
                << "named: " << eit->curve().data() << std::endl;

      // Rename the curve associated with the edge.
      arr.modify_edge (eit, X_monotone_curve_2 (eit->curve(), "overlap"));
    }
  }
  return 0;
}
Example #2
0
 Face_index_observer (Arrangement_2& arr) :
   CGAL::Arr_observer<Arrangement_2> (arr),
   n_faces (0)
 {
   CGAL_precondition (arr.is_empty());
   
   arr.unbounded_face()->set_data (0);
   n_faces++;
 }
Example #3
0
int main (int argc, char *argv[])
{
  // Get the name of the input file from the command line, or use the default
  // fan_grids.dat file if no command-line parameters are given.
  const char * filename = (argc > 1) ? argv[1] : "fan_grids.dat";

  // Open the input file.
  std::ifstream     in_file (filename);

  if (! in_file.is_open()) {
    std::cerr << "Failed to open " << filename << " ..." << std::endl;
    return (1);
  }

  // Read the segments from the file.
  // The input file format should be (all coordinate values are integers):
  // <n>                                 // number of segments.
  // <sx_1> <sy_1>  <tx_1> <ty_1>        // source and target of segment #1.
  // <sx_2> <sy_2>  <tx_2> <ty_2>        // source and target of segment #2.
  //   :      :       :      :
  // <sx_n> <sy_n>  <tx_n> <ty_n>        // source and target of segment #n.
  
  std::list<Segment_2>  segments;

  unsigned int n;
  in_file >> n;
  unsigned int i;
  for (i = 0; i < n; ++i) {
    int sx, sy, tx, ty;
    in_file >> sx >> sy >> tx >> ty;
    segments.push_back (Segment_2 (Point_2 (Number_type(sx), Number_type(sy)),
                                   Point_2 (Number_type(tx), Number_type(ty))));
  }
  in_file.close();

  // Construct the arrangement by aggregately inserting all segments.
  Arrangement_2                  arr;
  CGAL::Timer                    timer;

  std::cout << "Performing aggregated insertion of " 
            << n << " segments." << std::endl;

  timer.start();
  insert (arr, segments.begin(), segments.end());
  timer.stop();

  // Print the arrangement dimensions.
  std::cout << "V = " << arr.number_of_vertices()
	    << ",  E = " << arr.number_of_edges() 
	    << ",  F = " << arr.number_of_faces() << std::endl;

  std::cout << "Construction took " << timer.time() 
	    << " seconds." << std::endl;
  
  return 0;
}
Example #4
0
void
arrangement::keep_arc(Arrangement_2::Edge_iterator &e, Arrangement_2 &copy, Walk_pl &walk_pl)
{
    e->set_data("none");
    Conic_point_2 p;
    // if it is a segment
    if (e->curve().orientation() == CGAL::COLLINEAR)
    {
        Conic_point_2 source = e->curve().source();
        Conic_point_2 target = e->curve().target();
        double x = CGAL::to_double((target.x() + source.x()) /2);
        double y = CGAL::to_double((target.y() + source.y()) /2);
        Rational x_(x);
        Rational y_(y);
        p = Conic_point_2(x_,y_);
    }
    else // if it is an arc
    {
        int n = 2;
        approximated_point_2* points = new approximated_point_2[n + 1];
        e->curve().polyline_approximation(n, points); // there is 3 points
        p = Conic_point_2(Rational(points[1].first),Rational(points[1].second));
    }

    Arrangement_2::Vertex_handle v = insert_point(copy, p, walk_pl);
    try
    {
        if (v->face()->data() != 1)
            nonCriticalRegions.remove_edge(e, false, false);
        copy.remove_isolated_vertex(v);
    }
    catch (const std::exception exn) {}
}
bool test(const Arrangement_2& arr)
{
  if (arr.number_of_vertices() != 0) {
    std::cerr << "(A) Number of vertices (" << arr.number_of_vertices()
              << ") not 0!" << std::endl;
    return false;
  }

  // Check the validity more thoroughly.
  if (! CGAL::is_valid(arr)) {
    std::cerr << "The arrangement is NOT valid!" << std::endl;
    return false;
  }

  return true;
}
bool test_ray(Arrangement_2& arr, Face_handle f)
{
  Segment_2 s1(Point_2(0, 0), Point_2(1, 0));
  Halfedge_handle eh1 =
    arr.insert_in_face_interior(X_monotone_curve_2(s1), f);
  Vertex_handle vh = eh1->target();
  Ray_2 ray(Point_2(1, 0), Point_2(2, 0));
  Halfedge_handle eh2 =
    arr.insert_from_left_vertex(X_monotone_curve_2(ray), vh);

  // Remove the edges
  arr.remove_edge(eh2);
  arr.remove_edge(eh1);

  if (!::test(arr)) return false;

  return true;
}
Example #7
0
int main()
{
  Arrangement_2   arr;

  // Construct an arrangement of seven intersecting line segments.
  // We keep a handle for the vertex v_0 that corresponds to the point (1,1).
  Arrangement_2::Halfedge_handle  e =
    insert_non_intersecting_curve (arr, Segment_2 (Point_2 (1, 1),
                                                   Point_2 (7, 1)));
  Arrangement_2::Vertex_handle    v0 = e->source();
  insert (arr, Segment_2 (Point_2 (1, 1), Point_2 (3, 7)));
  insert (arr, Segment_2 (Point_2 (1, 4), Point_2 (7, 1)));
  insert (arr, Segment_2 (Point_2 (2, 2), Point_2 (9, 3)));
  insert (arr, Segment_2 (Point_2 (2, 2), Point_2 (4, 4)));
  insert (arr, Segment_2 (Point_2 (7, 1), Point_2 (9, 3)));
  insert (arr, Segment_2 (Point_2 (3, 7), Point_2 (9, 3)));

  // Create a mapping of the arrangement vertices to indices.
  Arr_vertex_index_map index_map(arr);

  // Perform Dijkstra's algorithm from the vertex v0.
  Edge_length_func edge_length;

  boost::vector_property_map<double, Arr_vertex_index_map> dist_map(static_cast<unsigned int>(arr.number_of_vertices()), index_map);



  boost::dijkstra_shortest_paths(arr, v0,
                                 boost::vertex_index_map(index_map).
                                 weight_map(edge_length).
                                 distance_map(dist_map));

  // Print the results:
  Arrangement_2::Vertex_iterator      vit;

  std::cout << "The distances of the arrangement vertices from ("
            << v0->point() << ") :" << std::endl;
  for (vit = arr.vertices_begin(); vit != arr.vertices_end(); ++vit)
    std::cout << "(" << vit->point() << ") at distance "
              << dist_map[vit] << std::endl;

  return 0;
}
Example #8
0
File: dual.cpp Project: FMX/CGAL
int main ()
{
  Arrangement_2   arr;

  // Construct an arrangement of seven intersecting line segments.
  insert (arr, Segment_2 (Point_2 (1, 1), Point_2 (7, 1)));
  insert (arr, Segment_2 (Point_2 (1, 1), Point_2 (3, 7)));
  insert (arr, Segment_2 (Point_2 (1, 4), Point_2 (7, 1)));
  insert (arr, Segment_2 (Point_2 (2, 2), Point_2 (9, 3)));
  insert (arr, Segment_2 (Point_2 (2, 2), Point_2 (4, 4)));
  insert (arr, Segment_2 (Point_2 (7, 1), Point_2 (9, 3)));
  insert (arr, Segment_2 (Point_2 (3, 7), Point_2 (9, 3)));

  // Create a mapping of the arrangement faces to indices.
  CGAL::Arr_face_index_map<Arrangement_2>      index_map (arr);

  // Perform breadth-first search from the unbounded face, and use the BFS
  // visitor to associate each arrangement face with its discover time.
  Discover_time_bfs_visitor<CGAL::Arr_face_index_map<Arrangement_2> >
                                               bfs_visitor (index_map);
  Arrangement_2::Face_handle                   uf = arr.unbounded_face();

  boost::breadth_first_search (Dual_arrangement_2 (arr), uf,
                               boost::vertex_index_map (index_map).
                               visitor (bfs_visitor));

  // Print the results:
  Arrangement_2::Face_iterator      fit;

  for (fit = arr.faces_begin(); fit != arr.faces_end(); ++fit)
  {
    std::cout << "Discover time " << fit->data() << " for ";
    if (fit != uf)
    {
      std::cout << "face ";
      print_ccb<Arrangement_2> (fit->outer_ccb());
    }
    else
      std::cout << "the unbounded face." << std::endl;
  }

  return (0);
}
Example #9
0
int main ()
{
  // Construct the arrangement containing two intersecting triangles.
  Arrangement_2          arr;
  Face_index_observer    obs (arr);

  Segment_2      s1 (Point_2(4, 1), Point_2(7, 6));
  Segment_2      s2 (Point_2(1, 6), Point_2(7, 6));
  Segment_2      s3 (Point_2(4, 1), Point_2(1, 6));
  Segment_2      s4 (Point_2(1, 3), Point_2(7, 3));
  Segment_2      s5 (Point_2(1, 3), Point_2(4, 8));
  Segment_2      s6 (Point_2(4, 8), Point_2(7, 3));

  insert_non_intersecting_curve (arr, s1);
  insert_non_intersecting_curve (arr, s2);
  insert_non_intersecting_curve (arr, s3);
  insert (arr, s4);
  insert (arr, s5);
  insert (arr, s6);

  // Go over all arrangement faces and print the index of each face and it
  // outer boundary. The face index is stored in its data field in our case.
  Arrangement_2::Face_const_iterator            fit;
  Arrangement_2::Ccb_halfedge_const_circulator  curr;

  std::cout << arr.number_of_faces() << " faces:" << std::endl;
  for (fit = arr.faces_begin(); fit != arr.faces_end(); ++fit) {
    std::cout << "Face no. " << fit->data() << ": ";
    if (fit->is_unbounded())
      std::cout << "Unbounded." << std::endl;
    else {
      curr = fit->outer_ccb();
      std::cout << curr->source()->point();
      do {
        std::cout << " --> " << curr->target()->point();
        ++curr;
      } while (curr != fit->outer_ccb());
      std::cout << std::endl;
    }
  }

  return 0;
}
Example #10
0
int main (int argc, char *argv[])
{
  // Get the name of the input file from the command line, or use the default
  // Bezier.dat file if no command-line parameters are given.
  const char   *filename = (argc > 1) ? argv[1] : "Bezier.dat";

  // Open the input file.
  std::ifstream   in_file (filename);

  if (! in_file.is_open()) {
    std::cerr << "Failed to open " << filename << std::endl;
    return 1;
  }

  // Read the curves from the input file.
  unsigned int               n_curves;
  std::list<Bezier_curve_2>  curves;
  Bezier_curve_2             B;
  unsigned int               k;
  
  in_file >> n_curves;
  for (k = 0; k < n_curves; k++) {
    // Read the current curve (specified by its control points).
    in_file >> B;
    curves.push_back (B);

    std::cout << "B = {" << B << "}" << std::endl;
  }

  // Construct the arrangement.
  Arrangement_2                     arr;
  insert (arr, curves.begin(), curves.end());

  // Print the arrangement size.
  std::cout << "The arrangement size:" << std::endl
            << "   V = " << arr.number_of_vertices()
            << ",  E = " << arr.number_of_edges() 
            << ",  F = " << arr.number_of_faces() << std::endl;

  return 0;
}
Example #11
0
int main()
{
    // Construct the arrangement of five intersecting segments.
    Arrangement_2  arr;
    Walk_pl        pl(arr);

    Segment_2      s1(Point_2(1, 0), Point_2(2, 4));
    Segment_2      s2(Point_2(5, 0), Point_2(5, 5));
    Segment_2      s3(Point_2(1, 0), Point_2(5, 3));
    Segment_2      s4(Point_2(0, 2), Point_2(6, 0));
    Segment_2      s5(Point_2(3, 0), Point_2(5, 5));

    insert_non_intersecting_curve(arr, s1, pl);
    insert_non_intersecting_curve(arr, s2, pl);
    insert(arr, s3, pl);
    insert(arr, s4, pl);
    insert(arr, s5, pl);

    // Print the size of the arrangement.
    std::cout << "The arrangement size:" << std::endl
              << "   V = " << arr.number_of_vertices()
              << ",  E = " << arr.number_of_edges()
              << ",  F = " << arr.number_of_faces() << std::endl;

    // Perform a point-location query on the resulting arrangement and print
    // the boundary of the face that contains it.
    Point_2 q(4, 1);
    Walk_pl::result_type obj = pl.locate(q);

    Arrangement_2::Face_const_handle  f;
    CGAL_assertion_code(bool success =) CGAL::assign(f, obj);

    CGAL_assertion(success);
    std::cout << "The query point (" << q << ") is located in: ";
    print_face<Arrangement_2>(f);

    return 0;
}
Example #12
0
int main()
{
  // Step(a) - construct a triangular face.
  Arrangement_2   arr;

  Segment_2       s1(Point_2(667, 1000), Point_2(4000, 5000));
  Segment_2       s2(Point_2(4000, 0), Point_2(4000, 5000));
  Segment_2       s3(Point_2(667, 1000), Point_2(4000, 0));

  Halfedge_handle e1 = arr.insert_in_face_interior(s1, arr.unbounded_face());
  Vertex_handle   v1 = e1->source();
  Vertex_handle   v2 = e1->target();
  Halfedge_handle e2 = arr.insert_from_right_vertex(s2, v2);
  Vertex_handle   v3 = e2->target();
  arr.insert_at_vertices(s3, v3, v1);

  // Step (b) - create additional two faces inside the triangle.
  Point_2         p1(4000, 3666), p2(4000, 1000);
  Segment_2       s4(Point_2(4000, 5000), p1);
  Segment_2       s5(p1, p2);
  Segment_2       s6(Point_2(4000, 0), p2);

  Halfedge_handle e4 = arr.split_edge(e2, s4, Segment_2(Point_2(4000, 0), p1));
  Vertex_handle   w1 = e4->target();
  Halfedge_handle e5 = arr.split_edge(e4->next(), s5, s6);
  Vertex_handle   w2 = e5->target();
  Halfedge_handle e6 = e5->next();

  Segment_2       s7(p1, Point_2(3000, 2666));
  Segment_2       s8(p2, Point_2(3000, 1333));
  Segment_2       s9(Point_2(3000, 2666), Point_2(2000, 1666));
  Segment_2       s10(Point_2(3000, 1333), Point_2(2000, 1666));
  Segment_2       s11(Point_2(3000, 1333), Point_2(3000, 2666));

  Halfedge_handle e7 = arr.insert_from_right_vertex(s7, w1);
  Vertex_handle   v4 = e7->target();
  Halfedge_handle e8 = arr.insert_from_right_vertex(s8, w2);
  Vertex_handle   v5 = e8->target();
  Vertex_handle   v6 =
    arr.insert_in_face_interior(Point_2(2000, 1666), e8->face());

  arr.insert_at_vertices(s9, v4, v6);
  arr.insert_at_vertices(s10, v5, v6);
  arr.insert_at_vertices(s11, v4, v5);

  // Step(c) - remove and merge faces to form a single hole in the traingle.
  arr.remove_edge(e7);
  arr.remove_edge(e8);

  e5 = arr.merge_edge(e5, e6, Segment_2(e5->source()->point(),
                                        e6->target()->point()));
  e2 = arr.merge_edge(e4, e5, s2);

  print_arrangement(arr);
  return 0;
}
Example #13
0
int main ()
{
  Arrangement_2   arr;
  Point_2         ps[N_POINTS];
  Vertex_handle   vhs[N_POINTS];
  bool            valid;
  int             k;

  ps[0] = Point_2 (2, 2);
  ps[1] = Point_2 (2, 7);
  ps[2] = Point_2 (4, 9);
  ps[3] = Point_2 (4, 5);
  ps[4] = Point_2 (5, 3);
  ps[5] = Point_2 (7, 1);
  ps[6] = Point_2 (7, 5);
  ps[7] = Point_2 (7, 7);
  ps[8] = Point_2 (9, 3);
  ps[9] = Point_2 (9, 6);

  for (k = 0; k < N_POINTS; k++)
  {
    vhs[k] = insert_point (arr, ps[k]);
  }

  arr.insert_from_left_vertex (Segment_2 (Point_2 (2, 7), Point_2 (4, 7)),
                               vhs[1]);
  TEST_VALIDITY(1);

  arr.insert_from_right_vertex (Segment_2 (Point_2 (6, 6), Point_2 (7, 5)),
                                vhs[6]);
  TEST_VALIDITY(2);

  arr.insert_at_vertices (Segment_2 (Point_2 (7, 1), Point_2 (9, 3)),
                          vhs[5], vhs[8]);
  TEST_VALIDITY(3);

  arr.insert_at_vertices (Segment_2 (Point_2 (7, 5), Point_2 (9, 3)),
                          vhs[6], vhs[8]);
  TEST_VALIDITY(4);

  arr.insert_from_right_vertex (Segment_2 (Point_2 (1, 1), Point_2 (2, 7)),
                                vhs[1]);
  TEST_VALIDITY(5);

  insert_non_intersecting_curve (arr,
                                 Segment_2 (Point_2 (1, 1), Point_2 (7, 1)));
  TEST_VALIDITY(6);

  insert_non_intersecting_curve (arr,
                                 Segment_2 (Point_2 (4, 7), Point_2 (6, 6)));
  TEST_VALIDITY(7);
  
  insert_non_intersecting_curve (arr,
                                 Segment_2 (Point_2 (2, 7), Point_2 (3, 3)));
  TEST_VALIDITY(8);

  insert_non_intersecting_curve (arr,
                                 Segment_2 (Point_2 (3, 3), Point_2 (7, 1)));
  TEST_VALIDITY(9);

  arr.insert_at_vertices (Segment_2 (Point_2 (7, 5), Point_2 (9, 6)),
                          vhs[6], vhs[9]);
  TEST_VALIDITY(10);

  std::cout << "Arrangement size:"
            << "   V = " << arr.number_of_vertices()
            << " (" << arr.number_of_isolated_vertices() << " isolated)"
            << ",  E = " << arr.number_of_edges() 
            << ",  F = " << arr.number_of_faces() << std::endl;
   
  // Check the validity more thoroughly.
  valid = is_valid(arr);
  std::cout << "Arrangement is "
            << (valid ? "valid." : "NOT valid!") << std::endl;

  return (0);
}
Example #14
0
int main()
{
  std::list<Curve_2>  curves;

  // Create a circle centered at the origin with squared radius 2.
  Kernel::Point_2 c1 = Kernel::Point_2(0, 0);
  Circle_2 circ1 = Circle_2(c1, CGAL::Exact_rational(2));

  curves.push_back(Curve_2(circ1));

  // Create a circle centered at (2,3) with radius 3/2 - note that
  // as the radius is rational we use a different curve constructor.
  Kernel::Point_2 c2 = Kernel::Point_2(2, 3);

  curves.push_back(Curve_2(c2, CGAL::Exact_rational(3, 2)));

  // Create a segment of the line (y = x) with rational endpoints.
  Kernel::Point_2 s3 = Kernel::Point_2(-2, -2);
  Kernel::Point_2 t3 = Kernel::Point_2(2, 2);
  Segment_2 seg3 = Segment_2(s3, t3);

  curves.push_back(Curve_2(seg3));

  // Create a line segment with the same supporting line (y = x), but
  // having one endpoint with irrational coefficients.
  CoordNT sqrt_15 = CoordNT(0, 1, 15); // = sqrt(15)
  Point_2 s4 = Point_2(3, 3);
  Point_2 t4 = Point_2(sqrt_15, sqrt_15);

  curves.push_back(Curve_2(seg3.supporting_line(), s4, t4));

  // Create a circular arc that correspond to the upper half of the
  // circle centered at (1,1) with squared radius 3. We create the
  // circle with clockwise orientation, so the arc is directed from
  // (1 - sqrt(3), 1) to (1 + sqrt(3), 1).
  Kernel::Point_2 c5 = Kernel::Point_2(1, 1);
  Circle_2 circ5 = Circle_2(c5, 3, CGAL::CLOCKWISE);
  CoordNT one_minus_sqrt_3 = CoordNT(1, -1, 3);
  CoordNT one_plus_sqrt_3 = CoordNT(1, 1, 3);
  Point_2 s5 = Point_2(one_minus_sqrt_3, CoordNT(1));
  Point_2 t5 = Point_2(one_plus_sqrt_3, CoordNT(1));

  curves.push_back(Curve_2(circ5, s5, t5));

  // Create a circular arc of the unit circle, directed clockwise from
  // (-1/2, sqrt(3)/2) to (1/2, sqrt(3)/2). Note that we orient the
  // supporting circle accordingly.
  Kernel::Point_2 c6 = Kernel::Point_2(0, 0);
  CoordNT sqrt_3_div_2 = CoordNT(CGAL::Exact_rational(0),
                                 CGAL::Exact_rational(1,2),
                                 CGAL::Exact_rational(3));
  Point_2 s6 = Point_2(CGAL::Exact_rational(-1, 2), sqrt_3_div_2);
  Point_2 t6 = Point_2(CGAL::Exact_rational(1, 2), sqrt_3_div_2);

  curves.push_back(Curve_2(c6, 1, CGAL::CLOCKWISE, s6, t6));

  // Create a circular arc defined by two endpoints and a midpoint,
  // all having rational coordinates. This arc is the upper-right
  // quarter of a circle centered at the origin with radius 5.
  Kernel::Point_2 s7 = Kernel::Point_2(0, 5);
  Kernel::Point_2 mid7 = Kernel::Point_2(3, 4);
  Kernel::Point_2 t7 = Kernel::Point_2(5, 0);

  curves.push_back(Curve_2(s7, mid7, t7));

  // Construct the arrangement of the curves.
  Arrangement_2 arr;

  insert(arr, curves.begin(), curves.end());

  // Print the size of the arrangement.
  std::cout << "The arrangement size:" << std::endl
            << "   V = " << arr.number_of_vertices()
            << ",  E = " << arr.number_of_edges()
            << ",  F = " << arr.number_of_faces() << std::endl;

  return 0;
}
Example #15
0
int main ()
{
  // Construct the initial arrangement.
  Arrangement_2   arr;
  Segment_2       segs[N_SEGMENTS];
  Halfedge_handle hhs[N_SEGMENTS];
  bool            valid;
  int             k;

  segs[0] = Segment_2 (Point_2 (5, 9), Point_2 (5, 11));
  segs[1] = Segment_2 (Point_2 (5, 9), Point_2 (7, 9));
  segs[2] = Segment_2 (Point_2 (5, 11), Point_2 (7, 9));
  segs[3] = Segment_2 (Point_2 (7, 6), Point_2 (9, 7));
  segs[4] = Segment_2 (Point_2 (9, 7), Point_2 (7, 9));
  segs[5] = Segment_2 (Point_2 (5, 9), Point_2 (7, 6));
  segs[6] = Segment_2 (Point_2 (10, 11), Point_2 (8, 13));
  segs[7] = Segment_2 (Point_2 (8, 13), Point_2 (11, 12));
  segs[8] = Segment_2 (Point_2 (10, 11), Point_2 (11, 12));
  segs[9] = Segment_2 (Point_2 (1, 20), Point_2 (5, 1));
  segs[10] = Segment_2 (Point_2 (5, 1), Point_2 (12, 6));
  segs[11] = Segment_2 (Point_2 (1, 20), Point_2 (12, 6));
  segs[12] = Segment_2 (Point_2 (13, 13), Point_2 (13, 15));
  segs[13] = Segment_2 (Point_2 (13, 15), Point_2 (15, 12));
  segs[14] = Segment_2 (Point_2 (13, 13), Point_2 (15, 12));
  segs[15] = Segment_2 (Point_2 (11, 12), Point_2 (13, 13));
  segs[16] = Segment_2 (Point_2 (1, 20), Point_2 (11, 17));
  segs[17] = Segment_2 (Point_2 (11, 17), Point_2 (20, 13));
  segs[18] = Segment_2 (Point_2 (12, 6), Point_2 (20, 13));
  segs[19] = Segment_2 (Point_2 (15, 12), Point_2 (20, 13));
  segs[20] = Segment_2 (Point_2 (5, 1), Point_2 (20, 1));
  segs[21] = Segment_2 (Point_2 (20, 1), Point_2 (20, 13));
  segs[22] = Segment_2 (Point_2 (15, 5), Point_2 (17, 3));
  segs[23] = Segment_2 (Point_2 (13, 3), Point_2 (17, 3));
  segs[24] = Segment_2 (Point_2 (12, 6), Point_2 (13, 3));
  segs[25] = Segment_2 (Point_2 (17, 3), Point_2 (20, 1));
  
  for (k = 0; k < N_SEGMENTS; k++)
  {
    hhs[k] = insert_non_intersecting_curve (arr, segs[k]);
  }
  valid = arr.is_valid();

  std::cout << "Arrangement size:"
            << "   V = " << arr.number_of_vertices()
            << ",  E = " << arr.number_of_edges() 
            << ",  F = " << arr.number_of_faces() << std::endl;
  std::cout << "The arrangement is "
            << (valid ? "valid." : "NOT valid!") << std::endl;
 
  if (! valid)
    return (1);

  // Remove some edges.
  int  del_indices[N_REMOVE] = {25, 23, 22, 1, 3, 11, 19, 15, 4, 24};

  for (k = 0; k < N_REMOVE; k++)
  {
    arr.remove_edge (hhs[del_indices[k]]);
    valid = arr.is_valid();
    std::cout << "  Removed " << k+1 << " segment(s), arrangement is "
              << (valid ? "valid." : "NOT valid!") << std::endl;

    if (! valid)
      return (1);
  }

  std::cout << "Final arrangement size:"
            << "   V = " << arr.number_of_vertices()
            << ",  E = " << arr.number_of_edges() 
            << ",  F = " << arr.number_of_faces() << std::endl;

  // Check the validity more thoroughly.
  valid = is_valid(arr);
  std::cout << "Arrangement is "
              << (valid ? "valid." : "NOT valid!") << std::endl;
 
  return (0);
}
Example #16
0
int main(int argc, char *argv[])
{
  // Get the name of the input file from the command line, or use the default
  // points.dat file if no command-line parameters are given.
  const char * filename = (argc > 1) ? argv[1] : "coll_points.dat";

  // Open the input file.
  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 consturct their dual lines.
  std::vector<Point_2>           points;
  std::list<X_monotone_curve_2>  dual_lines;

  unsigned int n;
  in_file >> n;
  points.resize(n);
  unsigned int k;
  for (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 dual_line = Line_2(CGAL::Exact_rational(px),
                              CGAL::Exact_rational(-1),
                              CGAL::Exact_rational(-py));

    // Generate the x-monotone curve based on the line and the point index.
    dual_lines.push_back(X_monotone_curve_2(dual_line, k));
  }
  in_file.close();

  // Construct the dual arrangement by aggragately inserting the lines.
  Arrangement_2 arr;

  insert(arr, dual_lines.begin(), dual_lines.end());

  // Look for vertices whose degree is greater than 4.
  Arrangement_2::Vertex_const_iterator vit;
  Arrangement_2::Halfedge_around_vertex_const_circulator circ;
  size_t d;

  for (vit = arr.vertices_begin(); vit != arr.vertices_end(); ++vit) {
    if (vit->degree() > 4) {
      // There should be vit->degree()/2 lines intersecting at the current
      // vertex. We print their primal points and their indices.
      circ = vit->incident_halfedges();
      for (d = 0; d < vit->degree() / 2; d++) {
        k = circ->curve().data();     // The index of the primal point.
        std::cout << "Point no. " << k+1 << ": (" << points[k] << "), ";
        ++circ;
      }
      std::cout << "are collinear." << std::endl;
    }
  }
  return 0;
}
Example #17
0
void
arrangement::compute_pointInCells(Arrangement_2 &arr, std::vector<std::vector<double> > &points)
{
    Walk_pl walk_pl(arr);

    int cpt = 0;
    for (Arrangement_2::Face_iterator face = arr.faces_begin(); face != arr.faces_end(); ++face)
    {
        if (face->is_unbounded())
            face->set_data(-1);
        else
        {
            // set data to each face
            face->set_data(cpt++);
            // find a point in this face
            Arrangement_2::Ccb_halfedge_circulator previous = face->outer_ccb();
            Arrangement_2::Ccb_halfedge_circulator first_edge = face->outer_ccb();
            Arrangement_2::Ccb_halfedge_circulator edge = face->outer_ccb();
            ++edge;
            do
            {
                std::vector<double> p1 = getPointMiddle(previous);
                std::vector<double> p2 = getPointMiddle(edge);
                std::vector<double> m;
                m.push_back((p1[0]+p2[0])/2);
                m.push_back((p1[1]+p2[1])/2);
                Rational x_(m[0]);
                Rational y_(m[1]);
                Conic_point_2 p(x_,y_);

                Arrangement_2::Vertex_handle v = insert_point(arr, p, walk_pl);
                try
                {
                    if (v->face()->data() == (cpt-1))
                    {
                        bool flag = false;
                        // test if it is not in holes and not in unbounded face
                        for (int i = 0; i < (int) convolutions_o.size(); ++i)
                        {
                            Walk_pl wpl(convolutions_o[i]);
                            Arrangement_2::Vertex_handle t = insert_point(convolutions_o[i], p, wpl);
                            if (t->face()->data() == 1)
                            {
                                convolutions_o[i].remove_isolated_vertex(t);
                                break;
                            }
                            else if (t->face()->data() == 2 || t->face()->data() == 0)
                            {
                                flag = true;
                                convolutions_o[i].remove_isolated_vertex(t);
                                break;
                            }
                        }

                        // then continue
                        if (!flag)
                            points.push_back(m);
                        else
                        {
                            --cpt;
                            face->set_data(-1);
                        }

                        arr.remove_isolated_vertex(v);
                        break;
                    }
                    arr.remove_isolated_vertex(v);
                }
                catch (const std::exception exn) {}
                previous = edge;

                ++edge;
            } while (edge != first_edge);
        }
    }
}
int main()
{
  Arrangement_2 arr;

  // Construct an arrangement of five linear objects.
  std::vector<X_monotone_curve_2>  curves;
  curves.push_back(Ray_2(Point_2(0, 0), Point_2(0, 1)));
  curves.push_back(Ray_2(Point_2(0, 0), Point_2(1, 0)));
  curves.push_back(Ray_2(Point_2(0, 0), Point_2(0, -1)));
  curves.push_back(Ray_2(Point_2(0, 0), Point_2(-1, 0)));
  curves.push_back(Ray_2(Point_2(0, 0), Point_2(1, 1)));
  curves.push_back(Ray_2(Point_2(0, 0), Point_2(1, -1)));
  curves.push_back(Ray_2(Point_2(0, 0), Point_2(-1, 1)));
  curves.push_back(Ray_2(Point_2(0, 0), Point_2(-1, -1)));

  std::vector<Halfedge_handle> hhs(curves.size());
  for (size_t i = 0; i < curves.size(); i++)
    hhs[i] = insert_non_intersecting_curve(arr, curves[i]);
  bool valid = arr.is_valid();
  std::cout << "Arrangement size:"
            << "   V = " << arr.number_of_vertices()
            << ",  E = " << arr.number_of_edges()
            << ",  F = " << arr.number_of_faces() << std::endl;
  std::cout << "The arrangement is "
            << (valid ? "valid." : "NOT valid!") << std::endl;
  if (! valid) return (1);

  // Remove the edges.
  for (size_t i = 0; i < hhs.size(); i++) {
    arr.remove_edge(hhs[i]);
    bool valid = arr.is_valid();
    std::cout << "  Removed " << i+1 << " curve(s), arrangement is "
              << (valid ? "valid." : "NOT valid!") << std::endl;

    if (! valid) return (1);
  }

  std::cout << "Final arrangement size:"
            << "   V = " << arr.number_of_vertices()
            << ",  E = " << arr.number_of_edges()
            << ",  F = " << arr.number_of_faces() << std::endl;

  if (!::test(arr)) return 1;

  /* Construct another arrangement of a segment connected to a ray.
   * First remove the ray, then remove the segment.
   *
   *  o---------------o
   *  |               |
   *  |               |
   *  |               |
   *  |       o--o----|
   *  |               |
   *  |               |
   *  |               |
   *  o---------------o
   */
  if (!test_ray(arr, arr.unbounded_face())) return 1;

  /* Construct another arrangement of a segment connected to a ray.
   * First remove the ray, then remove the segment.
   *
   *  o---------------o
   *  |               |
   *  |               |
   *  |               |
   *  |       o--o----|
   *  |               |
   *  o---------------o
   *  |               |
   *  o---------------o
   */
  Line_2 l1(Point_2(0, -1), Point_2(1, -1));
  Halfedge_handle eh1 =
    arr.insert_in_face_interior(X_monotone_curve_2(l1), arr.unbounded_face());

  if (!test_ray(arr, eh1->face())) return 1;
  arr.remove_edge(eh1);

  /* Construct another arrangement of a segment connected to a ray.
   * First remove the ray, then remove the segment.
   *
   *  o-----o---------o
   *  |     |         |
   *  |     |         |
   *  |     |         |
   *  |     | o--o----|
   *  |     |         |
   *  |     |         |
   *  |     |         |
   *  o-----o---------o
   */
  Line_2 l2(Point_2(-1, 0), Point_2(-1, 1));
  Halfedge_handle eh2 =
    arr.insert_in_face_interior(X_monotone_curve_2(l2), arr.unbounded_face());

  if (!test_ray(arr, eh2->twin()->face())) return 1;
  arr.remove_edge(eh2);

  return 0;
}
int main ()
{
  CGAL::set_pretty_mode(std::cout);             // for nice printouts.
  
  // Traits class object 
  AK1 ak1; 
  Traits_2 traits(&ak1);
    
  // constructor for rational functions 
  Traits_2::Construct_curve_2 construct = traits.construct_curve_2_object(); 
  
  // a polynomial representing x .-)
  Polynomial_1 x = CGAL::shift(Polynomial_1(1),1);
  
  // container storing all arcs 
  std::vector<Traits_2::Curve_2>  arcs;

  
  // Create the rational functions (y = 1 / x), and (y = -1 / x).
  Polynomial_1 P1(1);
  Polynomial_1 minusP1(-P1);
  Polynomial_1 Q1 = x;
  arcs.push_back(construct(P1, Q1));
  arcs.push_back(construct(minusP1, Q1));

  // Create a bounded segments of the parabolas (y = -4*x^2 + 3) and
  // (y = 4*x^2 - 3), defined over [-sqrt(3)/2, sqrt(3)/2].
  Polynomial_1 P2 = -4*x*x+3; 
  Polynomial_1 minusP2 = -P2; 
  std::vector<std::pair<Alg_real_1,int> > roots;

  // [-sqrt(3)/2, sqrt(3)/2]
  traits.algebraic_kernel_d_1()->solve_1_object()(P2, std::back_inserter(roots));
  arcs.push_back(construct(P2, roots[0].first, roots[1].first));
  arcs.push_back(construct(minusP2, roots[0].first, roots[1].first));

  // Create the rational function (y = 1 / 2*x) for x > 0, and the
  // rational function (y = -1 / 2*x) for x < 0.
  Polynomial_1 P3(1);
  Polynomial_1 minusP3(-P3);
  Polynomial_1 Q3 = 2*x;
  arcs.push_back(construct(P3, Q3, Alg_real_1(0), true));
  arcs.push_back(construct(minusP3, Q3, Alg_real_1(0), false));

  // Construct the arrangement of the six arcs.
  //Arrangement_2 arr(&traits);
  Arrangement_2 arr;
  insert(arr, arcs.begin(), arcs.end());

  // Print the arrangement size.
  std::cout << "The arrangement size:" << std::endl
    << "   V = " << arr.number_of_vertices()
    << " (plus " << arr.number_of_vertices_at_infinity()
    << " at infinity)"
    << ",  E = " << arr.number_of_edges() 
    << ",  F = " << arr.number_of_faces() 
    << " (" << arr.number_of_unbounded_faces() << " unbounded)"
    << std::endl << std::endl;

  return 0;
}
void CriticalCurves::setParameters(double radius_1, double radius_2, Arrangements_2 insets_1, Arrangements_2 insets_2)
{
    Arrangement_2_iterator inset_1 = insets_1.begin();
    Arrangement_2_iterator inset_2 = insets_2.begin();

    while (inset_1 != insets_1.end() && inset_2 != insets_2.end())
    {
        Arrangement_2 arrangement;

        // Add the curves of the inset.
        for (Edge_iterator edge = inset_1->edges_begin(); edge != inset_1->edges_end(); ++edge)
        {
            insert(arrangement, edge->curve());
        }

        // Add the critical curves of type I.
        for (Edge_iterator edge = inset_2->edges_begin(); edge != inset_2->edges_end(); ++edge)
        {
            if (CGAL::COLLINEAR == edge->curve().orientation())
            {
                // Displaced a segment.
                Nt_traits nt_traits;
                Algebraic_ft factor = nt_traits.convert(Rational(radius_1) + Rational(radius_2));
                Conic_point_2 source = edge->curve().source();
                Conic_point_2 target = edge->curve().target();
                Algebraic_ft delta_x = target.x() - source.x();
                Algebraic_ft delta_y = target.y() - source.y();
                Algebraic_ft length = nt_traits.sqrt(delta_x * delta_x + delta_y * delta_y);
                Algebraic_ft translation_x = factor * delta_y / length;
                Algebraic_ft translation_y = - factor * delta_x / length;
                Conic_point_2 point_1(source.x() + translation_x, source.y() + translation_y);
                Conic_point_2 point_2(target.x() + translation_x, target.y() + translation_y);
                Algebraic_ft a = - delta_y;
                Algebraic_ft b = delta_x;
                Algebraic_ft c = factor * length - (source.y() * target.x() - source.x() * target.y());
                X_monotone_curve_2 x_monotone_curve(a, b, c, point_1, point_2);
                insert(arrangement, x_monotone_curve);
            }
            else
            {
                // Displaces an arc.
                Rational two(2);
                Rational four(4);

                Rational r = edge->curve().r();
                Rational s = edge->curve().s();
                Rational t = edge->curve().t();
                Rational u = edge->curve().u();
                Rational v = edge->curve().v();
                Rational w = edge->curve().w();

                Nt_traits nt_traits;
                Rational x_center = - u / (two * r);
                Rational y_center = - v / (two * r);
                Rat_point_2 rat_center(x_center, y_center);
                Conic_point_2 center(nt_traits.convert(x_center), nt_traits.convert(y_center));

                Rational radius = Rational(radius_1) + two * Rational(radius_2);

                Algebraic_ft coefficient = nt_traits.convert(radius / Rational(radius_2));

                Conic_point_2 source_1 = edge->curve().source();
                Algebraic_ft x_source_2 = center.x() + coefficient * (source_1.x() - center.x());
                Algebraic_ft y_source_2 = center.y() + coefficient * (source_1.y() - center.y());
                Conic_point_2 source_2(x_source_2, y_source_2);

                Conic_point_2 target_1 = edge->curve().target();
                Algebraic_ft x_target_2 = center.x() + coefficient * (target_1.x() - center.x());
                Algebraic_ft y_target_2 = center.y() + coefficient * (target_1.y() - center.y());
                Conic_point_2 target_2(x_target_2, y_target_2);

                Rat_circle_2 circle(rat_center, radius * radius);

                Conic_arc_2 conic_arc(circle, CGAL::COUNTERCLOCKWISE, source_2, target_2);

                insert(arrangement, conic_arc);
            }
        }

        // Add the critical curves of type II.
        for (Edge_iterator edge = inset_2->edges_begin(); edge != inset_2->edges_end(); ++edge)
        {
            double x = CGAL::to_double(edge->curve().source().x());
            double y = CGAL::to_double(edge->curve().source().y());
            double radius = radius_1 + radius_2;
            Rat_point_2 center(x, y);
            Rat_circle_2 circle(center, radius * radius);
            Conic_arc_2 conic_arc(circle);
            insert(arrangement, conic_arc);
        }

        // Remove the curves which are not include in the inset.
        Objects objects;
        Face_handle face;
        for (Edge_iterator edge = arrangement.edges_begin(); edge != arrangement.edges_end(); ++edge)
        {
            CGAL::zone(*inset_1, edge->curve(), std::back_inserter(objects));
            for (Object_iterator object = objects.begin(); object != objects.end(); ++object)
            {
                if (assign(face, *object))
                {
                    if (face->is_unbounded())
                    {
                        remove_edge(arrangement, edge);
                        break;
                    }
                }
            }
            objects.clear();
        }

        // Print essential information on the standard input.
        std::cout << "Arrangement:" << std::endl;
        std::cout << "  Number of vertices: " << arrangement.number_of_vertices() << std::endl;
        std::cout << "  Number of edges   : " << arrangement.number_of_edges() << std::endl;
        std::cout << "  Number of face    : " << arrangement.number_of_faces() << std::endl;

        this->critical_curves.push_back(arrangement);

        ++inset_1;
        ++inset_2;
    }

    // Commit changes.
    emit(criticalCurvesChanged());
    return;
}
Example #21
0
int main ()
{
  // Construct an arrangement containing three RED line segments.
  Arrangement_2     arr;
  Landmarks_pl      pl (arr);

  Segment_2         s1 (Point_2(-1, -1), Point_2(1, 3));
  Segment_2         s2 (Point_2(2, 0), Point_2(3, 3));
  Segment_2         s3 (Point_2(0, 3), Point_2(2, 5));

  insert (arr, Colored_segment_2 (s1, RED), pl);
  insert (arr, Colored_segment_2 (s2, RED), pl);
  insert (arr, Colored_segment_2 (s3, RED), pl);

  // Insert three BLUE line segments.
  Segment_2         s4 (Point_2(-1, 3), Point_2(4, 1));
  Segment_2         s5 (Point_2(-1, 0), Point_2(4, 1));
  Segment_2         s6 (Point_2(-2, 1), Point_2(1, 4));

  insert (arr, Colored_segment_2 (s4, BLUE), pl);
  insert (arr, Colored_segment_2 (s5, BLUE), pl);
  insert (arr, Colored_segment_2 (s6, BLUE), pl);

  // Go over all vertices and print just the ones corresponding to intersection
  // points between RED segments and BLUE segments. Note that we skip endpoints
  // of overlapping sections.
  Arrangement_2::Vertex_const_iterator   vit;
  Segment_color                          color;

  for (vit = arr.vertices_begin(); vit != arr.vertices_end(); ++vit) {
    // Go over the incident halfedges of the current vertex and examine their
    // colors.
    bool       has_red = false;
    bool       has_blue = false;

    Arrangement_2::Halfedge_around_vertex_const_circulator  eit, first;

    eit = first = vit->incident_halfedges();
    do {
      // Get the color of the current half-edge.
      if (eit->curve().data().size() == 1) {
        color = eit->curve().data().front();

        if (color == RED)
          has_red = true;
        else if (color == BLUE)
          has_blue = true;
      }

      ++eit;
    } while (eit != first);

    // Print the vertex only if incident RED and BLUE edges were found.
    if (has_red && has_blue)
    {
      std::cout << "Red-blue intersection at (" << vit->point() << ")"
                << std::endl;
    }
  }

  // Locate the edges that correspond to a red-blue overlap.
  Arrangement_2::Edge_iterator   eit;

  for (eit = arr.edges_begin(); eit != arr.edges_end(); ++eit)
  {
    // Go over the incident edges of the current vertex and examine their
    // colors.
    bool       has_red = false;
    bool       has_blue = false;

    Traits_2::Data_container::const_iterator       dit;

    for (dit = eit->curve().data().begin(); dit != eit->curve().data().end();
         ++dit)
    {
      if (*dit == RED)
        has_red = true;
      else if (*dit == BLUE)
        has_blue = true;
    }

    // Print the edge only if it corresponds to a red-blue overlap.
    if (has_red && has_blue)
      std::cout << "Red-blue overlap at [" << eit->curve() << "]"  << std::endl;
  }
  return 0;
}