Ejemplo n.º 1
0
void ArrPolyIpelet::protected_run(int fn){
  if (fn==1) {
    show_help();
    return;
  }

  X_monotone_list output_curves;
  Curve_list input_curves;
  //Argt
  std::list<Segment_2> sg_list;
  std::list<Circle_2> cir_list;
  std::list<Polygon_2> pol_list;
  std::list<Circular_arc_2> arc_list;

  read_active_objects(
    CGAL::dispatch_or_drop_output<Polygon_2,Circle_2,Segment_2,Circular_arc_2>(
      std::back_inserter(pol_list),
      std::back_inserter(cir_list),
      std::back_inserter(sg_list),
      std::back_inserter(arc_list)
    ),
    true,true
  );

  for (std::list<Polygon_2>::iterator it=pol_list.begin();it!=pol_list.end();++it)
    for(Polygon_2::Edge_const_iterator edge_it=it->edges_begin();edge_it!=it->edges_end();++edge_it)
      input_curves.push_back(Curve_2(edge_it->point(0),edge_it->point(1)));

  for (std::list<Segment_2>::iterator it=sg_list.begin();it!=sg_list.end();++it)
    input_curves.push_back(Curve_2(it->point(0),it->point(1)));

  for (std::list<Circle_2>::iterator it=cir_list.begin();it!=cir_list.end();++it)
    input_curves.push_back(Curve_2(it->center(),sqrt(CGAL::to_double(it->squared_radius()))));

  for (std::list<Circular_arc_2>::iterator it=arc_list.begin();it!=arc_list.end();++it)
    input_curves.push_back(
      Curve_2( std::get<0>(*it).center(),
               sqrt(CGAL::to_double(std::get<0>(*it).squared_radius())),
               std::get<3>(*it),
               Traits::Point_2(std::get<1>(*it).x(),std::get<1>(*it).y()),
               Traits::Point_2(std::get<2>(*it).x(),std::get<2>(*it).y())
             )
      );

  Traits T;
  CGAL::compute_subcurves(input_curves.begin(),input_curves.end(),std::back_inserter(output_curves),false,T);




  for (X_monotone_list::iterator it=output_curves.begin();it!=output_curves.end();++it){
    Point_2 S(CGAL::to_double(it->source().x()),CGAL::to_double(it->source().y()));
    Point_2 T(CGAL::to_double(it->target().x()),CGAL::to_double(it->target().y()));
    if (it->is_linear ())
      draw_in_ipe(Segment_2(S,T));
    if (it->is_circular())
      draw_in_ipe(Circular_arc_2(it->supporting_circle(),S,T,it->supporting_circle().orientation()));
  }
  return;
}
Ejemplo n.º 2
0
// This routine checks whether a poylgon can be inserted into a block such that the interior of the polygon does not at all overlap with used space
// in the block.  We COULD do this using boolean operations (E.g. is the intersection of the used block space and our polygon empty?) but we do NOT want
// to.  Why?  Time to do a boolean op is a function of BOTH polygons, and in a lot of cases the block will be HUGELY complex (imagine a giant forest expanse
// with lots of crap already inserted into it) and our test block will be TINY (a quad).  In this case, we get better performance by doing a piece-wise per-side
// test.  
// Side note: using the bulk locator totally violates this principle...we will probably need to replace it with a walk location strategy.
// So we use the zone utility to see what we'll hit as we go along our edges.  
bool	can_insert_into_block(
					Block_2&						block,
					const Polygon_2&				bounds)
{
	// Run a bulk location on the entire block...TBD: there may be blocks where sweeping is worse than marching.
	// Anyway, we get a bunch of pairs of the locate point and the actual part of the arrangement we hit.
	vector<pair<Point_2, CGAL::Object> >	pts;
	CGAL::locate(block, bounds.vertices_begin(), bounds.vertices_end(), back_inserter(pts));
	
	// Quick check: if ANY of our points are inside a non empty face, we are by definition hosed.
	// We can see this now just from the location data.
	Block_2::Face_const_handle ff;
	for(int n = 0; n < pts.size(); ++n)
	if(CGAL::assign(ff,pts[n].second))
	if(ff->data().usage != usage_Empty)
		return false;

	for(int n = 0; n < pts.size(); ++n)
	{
		// We are now going to go through each side and do a zone test.  This will check whether it is 
		// either running along a full area or crashing through it.
		int m = (n+1)%pts.size();
		check_block_visitor	v;
		v.cv = Block_2::X_monotone_curve_2(Segment_2(pts[n].first, pts[m].first));

		CGAL::Arrangement_zone_2<Block_2,check_block_visitor>	zone(block, &v);

		if(v.cv.is_directed_right())
			zone.init_with_hint(v.cv,pts[n].second);
		else
			zone.init_with_hint(v.cv,pts[m].second);

		zone.compute_zone();
		
		if(!v.ok)
			return false;		
	}
	return true;
}
Ejemplo n.º 3
0
Segment_2 project_2(const Segment_3& s)
{
  return Segment_2(s.source().point_2(), s.target().point_2());
}
Ejemplo n.º 4
0
void triangulate(const Polygon_2& polygon, 
		 Cut_iter cuts_begin, Cut_iter cuts_end,
		 const boost::unordered_map<Point_3, boost::unordered_set<Segment_3_undirected> >& point2edges,
		 Out_iter triangles)
{
  typedef CGAL::Triangulation_vertex_base_2<Kernel>                     Vb;
  typedef CGAL::Triangulation_vertex_base_with_info_2<Point_3, Kernel, Vb>     Info;
  typedef CGAL::Constrained_triangulation_face_base_2<Kernel>           Fb;
  typedef CGAL::Triangulation_data_structure_2<Info,Fb>              TDS;
  typedef CGAL::Exact_predicates_tag                               Itag;
  typedef CGAL::Constrained_Delaunay_triangulation_2<Kernel, TDS, Itag> CDT;
  typedef CDT::Vertex_handle Vertex_handle;

  static log4cplus::Logger logger = log4cplus::Logger::getInstance("polygon_utils");

  Polygon_2 p(polygon);
  LOG4CPLUS_TRACE(logger, "Triangulating " << pp(p));
  if (p.size() < 3) return;

  bool vertical = is_vertical(p);
  if (vertical)
  {
    LOG4CPLUS_TRACE(logger, "Polygon is vertical.  Rotating.");
    p = yz_swap_neg(p);
  }

  bool reverse = !p.is_counterclockwise_oriented();
  if (reverse)
    p.reverse_orientation();

  CDT cdt;

  boost::unordered_map<Point_3, Vertex_handle> point2handle;
  for (Polygon_2::Vertex_iterator it = p.vertices_begin(); it != p.vertices_end(); ++it)
  {
    Vertex_handle h = cdt.insert(*it);
    point2handle[*it] = h;
    h->info() = *it;//it->z();
  }

  Polygon_2::Vertex_circulator start = p.vertices_circulator();
  Polygon_2::Vertex_circulator c = start;
  Polygon_2::Vertex_circulator n = c;
  ++n;
  do
  {
    Vertex_handle ch = point2handle[*c];//cdt.insert(*c);
    Vertex_handle nh = point2handle[*n];//cdt.insert(*n);
//     ch->info() = c->z();
//     nh->info() = n->z();
//     cdt.insert_constraint(*c, *n);
    cdt.insert_constraint(ch, nh);
    ++c;
    ++n;
  } while (c != start);

  for (Cut_iter c_it = cuts_begin; c_it != cuts_end; ++c_it)
  {
    Polyline_2 cut = *c_it;
    LOG4CPLUS_TRACE(logger, "Adding cut: " << pp(cut));
    if (vertical)
      cut = yz_swap_neg(cut);
    for (Polyline_2::const_iterator c = cut.begin(); c != cut.end(); ++c)
    {
      Polyline_2::const_iterator n = c;
      ++n;
      if (n != cut.end())
      {
	const Point_3& cp = *c;
	const Point_3& np = *n;
	if (point2handle.find(cp) == point2handle.end())
	{
	  Vertex_handle h = cdt.insert(cp);
	  point2handle[cp] = h;
	  h->info() = cp;//cp.z();
	}
	if (point2handle.find(np) == point2handle.end())
	{
	  Vertex_handle h = cdt.insert(np);
	  point2handle[np] = h;
	  h->info() = np;//np.z();
	}

	Vertex_handle ch = point2handle[*c];//cdt.insert(*c);
	Vertex_handle nh = point2handle[*n];//cdt.insert(*n);
// 	ch->info() = c->z();
// 	nh->info() = n->z();
// 	cdt.insert_constraint(*c, *n);
	cdt.insert_constraint(ch, nh);
	LOG4CPLUS_TRACE(logger, "  " << pp(Segment_2(*c, *n)));
      }
    }
  }

  // Loop through the triangulation and store the vertices of each triangle
  for (CDT::Finite_faces_iterator ffi = cdt.finite_faces_begin();
       ffi != cdt.finite_faces_end();
       ++ffi)
  {
    Triangle t;
    Point_3 center = centroid(ffi->vertex(0)->info(), ffi->vertex(1)->info(), ffi->vertex(2)->info());
    if (p.has_on_bounded_side(center) && 
	is_legal(ffi->vertex(0)->info(), ffi->vertex(1)->info(), ffi->vertex(2)->info(), point2edges))
    {
      for (int i = 0; i < 3; ++i)
      {
	int idx = reverse ? 2-i : i;
	if (!vertical)
	{
// 	  Point_3 p(ffi->vertex(i)->point());
// 	  p = Point_3(p.x(), p.y(), ffi->vertex(i)->info());
	  Point_3 p(ffi->vertex(i)->info());
	  t[idx] = p;
	}
	else
	{
// 	  Point_3 p(ffi->vertex(i)->point());
// 	  p = Point_3(p.x(), p.y(), ffi->vertex(i)->info());
	  Point_3 p(ffi->vertex(i)->info());
	  t[idx] = yz_swap_pos(p);
	}
      }
      LOG4CPLUS_TRACE(logger, "Adding tile: " << pp_tri(t));
      *triangles++ = t;
    }
  }
}
Ejemplo n.º 5
0
void SubSelectIpelet::protected_run(int fn)
{
  if (fn==2) {
    show_help();
    return;
  }
  
  std::list<Circle_2> cir_list;
  std::list<Polygon_2> pol_list;
  
  Iso_rectangle_2 bbox=
    read_active_objects(
      CGAL::dispatch_or_drop_output<Polygon_2,Circle_2>(
        std::back_inserter(pol_list),
        std::back_inserter(cir_list)
      )
    );  
  
  
  if (fn==0 && pol_list.size()!=2){
    print_error_message("You must select exactly two polygons");
    return;
  }  
  
  
  std::list<double> r_offsets;
  for (std::list<Circle_2>::iterator it=cir_list.begin();it!=cir_list.end();++it)
    r_offsets.push_back(sqrt(CGAL::to_double(it->squared_radius())));
  
  IpeMatrix tfm (1,0,0,1,-CGAL::to_double(bbox.min().x()),-CGAL::to_double(bbox.min().y()));
  
  for (std::list<Polygon_2>::iterator it=pol_list.begin();it!=pol_list.end();++it)
    if(!it->is_simple()){
      print_error_message("Polygon(s) must be simple");
    }
  
  
  if (fn==0){
    Polygon_2 polygon1=*pol_list.begin();
    Polygon_2 polygon2=*++pol_list.begin();
    Polygon_with_holes_2  sum = minkowski_sum_2 (polygon1, polygon2);
    std::list<Point_2> LP;
    for (Polygon_2::iterator it=sum.outer_boundary().vertices_begin();it!= sum.outer_boundary().vertices_end();++it)
      LP.push_back(*it);
    draw_polyline_in_ipe(LP.begin(),LP.end(),true,false,false);
    
    for (Polygon_with_holes_2::Hole_const_iterator poly_it = sum.holes_begin(); poly_it != sum.holes_end();
          ++poly_it){
      LP.clear();
      for (Polygon_2::iterator it=poly_it->vertices_begin();it!= poly_it->vertices_end();++it)
        LP.push_back(*it);
      draw_polyline_in_ipe(LP.begin(),LP.end(),true,false,false);
    }
    
    create_polygon_with_holes(true);
    transform_selected_objects_(tfm);
  }
  else{
    if (r_offsets.size()==0)
      r_offsets.push_back(10);
    for (std::list<Polygon_2>::iterator it_pol=pol_list.begin();it_pol!=pol_list.end();++it_pol){
      for(std::list<double>::iterator it=r_offsets.begin();it!=r_offsets.end();++it){
        Offset_polygon_with_holes_2  offset=approximated_offset_2 (*it_pol, *it, 0.0001);
        std::list<Segment_2> LS;
        for( Offset_polygon_2::Curve_iterator itt=offset.outer_boundary().curves_begin();
          itt!=offset.outer_boundary().curves_end();++itt){
          Point_2 S=Point_2(CGAL::to_double(itt->source().x()),CGAL::to_double(itt->source().y()));
          Point_2 T=Point_2(CGAL::to_double(itt->target().x()),CGAL::to_double(itt->target().y()));
          if (itt->is_linear ())
            LS.push_back(Segment_2(S,T));
          if (itt->is_circular())
            draw_in_ipe(Circular_arc_2(itt->supporting_circle(),S,T,itt->supporting_circle().orientation()));
        }
        draw_in_ipe(LS.begin(),LS.end());
      }
    }
  }
}
Ejemplo n.º 6
0
void Cone_spanners_ipelet::protected_run(int fn)
{
  std::vector<Point_2> lst;
  int number_of_cones;
  switch (fn){
    case 0:
    case 1:
    case 2:
    case 3:
    case 4:
    case 5:
    case 6:
    {
      std::vector<Point_2> points_read;
      read_active_objects(
        CGAL::dispatch_or_drop_output<Point_2>(std::back_inserter(points_read))
      );

      if (points_read.empty()) {
        print_error_message("No mark selected");
        return;
      }
      for(std::vector<Point_2>::iterator it = points_read.begin(); it != points_read.end(); it++) {
        if(std::find(points_read.begin(), it, *it) == it) {
          lst.push_back(*it);
        }
      }

      int ret_val;
      boost::tie(ret_val,number_of_cones)=request_value_from_user<int>("Enter the number of cones");
      if (ret_val < 0) {
        print_error_message("Incorrect value");
        return;
      }
      if(number_of_cones < 2) {
        print_error_message("The number of cones must be larger than 1!");
        return;
      }
      break;
    }
    case 7:
      show_help();
      return;
  }

  if(fn >= 0 && fn <= 5) {
    CGAL::Cones_selected cones_selected = CGAL::ALL_CONES;
    if(fn == 2 || fn == 3)
      cones_selected = CGAL::EVEN_CONES;
    else if(fn == 4 || fn == 5)
      cones_selected = CGAL::ODD_CONES;

    Graph g;
    switch (fn){
      case 0:
      case 2:
      case 4:
      {
        CGAL::Construct_theta_graph_2<Kernel, Graph> theta(number_of_cones, Direction_2(1,0), cones_selected);
        theta(lst.begin(), lst.end(), g);
        break;
      }
      case 1:
      case 3:
      case 5:
      {
        CGAL::Construct_yao_graph_2<Kernel, Graph> yao(number_of_cones, Direction_2(1,0), cones_selected);
        yao(lst.begin(), lst.end(), g);
        break;
      }
    }
    boost::graph_traits<Graph>::edge_iterator ei, ei_end;
    for (boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) {
      boost::graph_traits<Graph>::edge_descriptor e = *ei;
      boost::graph_traits<Graph>::vertex_descriptor  u = source(e, g);
      boost::graph_traits<Graph>::vertex_descriptor  v = target(e, g);
      draw_in_ipe(Segment_2(g[u], g[v]));
    }
    group_selected_objects_();
  }
  else if(fn == 6) {
    CGAL::Compute_cone_boundaries_2<Kernel> cones;
    std::vector<Direction_2> directions(number_of_cones);
    cones(number_of_cones, Direction_2(1,0), directions.begin());
    for(std::vector<Point_2>::iterator it = lst.begin(); it != lst.end(); it++) {
      for(std::vector<Direction_2>::iterator dir = directions.begin(); dir != directions.end(); dir++) {
        draw_in_ipe(Segment_2(*it,*it + 100*dir->to_vector()));
      }
      group_selected_objects_();
      get_IpePage()->deselectAll();
    }
  }
}