/* Jarvis march visualization this time we use the special kernel ... */ #define CGAL_CH_NO_POSTCONDITIONS #define CGAL_PROVIDE_LEDA_RAT_KERNEL_TRAITS_3 #define CGAL_NO_DEPRECATED_CODE #include #if !defined(CGAL_USE_LEDA) || (__LEDA__ < 420) #include int main(int argc, char *argv[]) { std::cout << "No LEDA 4.2 or higher installed!\n"; std::cout << "A LEDA version >= 4.2 is required !\n"; return 0; } #else #include #include #include #include #include #include #include #include #include #if defined(LEDA_NAMESPACE) using namespace leda; #endif typedef CGAL::leda_rat_kernel_traits LEDA_KERNEL; typedef CGAL::kernel_event KEV; typedef CGAL::kernel_event KRES; typedef CGAL::Kernel_special K; typedef K::Less_rotate_ccw_2 Less_rotate_ccw_2; typedef K::Point_2 Point; typedef K::Segment_2 Segment; class geo_hull : public geowin_update, std::list > { public: CGAL::event_item less_rotate_ccw_it; CGAL::event_item less_xy_it; int less_rotate_ccw_counter; int less_xy_counter; GeoWin& gw; leda_window& w; std::list current_hull; leda_point_style pold; const std::list* input_set; geo_hull(GeoWin& g) : gw(g), w(g.get_window()) { less_rotate_ccw_counter=0; less_xy_counter=0; input_set = NULL; } virtual ~geo_hull() { } // -------------------------------------------------------------------------------------------------- // event handling ... // -------------------------------------------------------------------------------------------------- void user_interaction() { w.read_mouse(); } void draw_points() { std::cout << "draw_points !\n"; leda_point_style ps = w.set_point_style(leda_cross_point); std::list::const_iterator it= input_set->begin(); for(;it != input_set->end(); it++) w.draw_point(it->to_float()); w.set_point_style(ps); } void draw_current_hull() { //w.clear(); w.draw_box(-2000,-2000,4000,4000,white); //w.read_mouse(); //w.stop_buffering(); draw_points(); std::list::const_iterator cit = current_hull.begin(); Point plast; bool first = true; for(;cit != current_hull.end(); cit++){ w.draw_point((*cit).to_float(), leda_green); if (! first) w.draw_segment((*cit).to_float(), plast.to_float(), leda_green); plast = *cit; first= false; } } void less_rotate_ccw_occurence(const LEDA_KERNEL::Less_rotate_ccw_2& fcn, const Point& p1, const Point& p2, const Point& p3, const bool& result) { less_rotate_ccw_counter++; std::cout << "less_rotate_ccw:" << p1 << " " << p2 << " " << p3 << "\n"; //store hull ... if (current_hull.empty() || p1 != current_hull.front()) current_hull.push_front(p1); if (result) { draw_current_hull(); gw.msg_clear(); gw.msg_open(leda_string("less_rotate_ccw - new point found ...")); w.draw_ray(p1.to_float(), p2.to_float(), leda_blue); w.draw_arrow(p2.to_float(), p3.to_float(), leda_black); user_interaction(); } } void less_xy_occurence(const LEDA_KERNEL::Less_xy_2& fcn, const Point& p1, const Point& p2, const bool& result) { std::cout << "less_xy:" << p1 << " " << p2 << "\n"; if (less_xy_counter == 0) // draw start point ... w.draw_point(p1.to_float(), leda_red); if (result) { w.draw_point(p1.to_float(), leda_red); gw.msg_clear(); gw.msg_open(leda_string("new minimum point (xy-lexicographically) found ...")); user_interaction(); } less_xy_counter++; } void init_visualization(const std::list& L) { less_rotate_ccw_counter = 0; less_rotate_ccw_counter = 0; /* less_rotate_ccw_it = CGAL::attach(CGAL::Predicate_leda_rat_less_rotate_ccw_2::ev_leda_rat_point, \ *this, &geo_hull::less_rotate_ccw_occurence); less_xy_it = CGAL::attach(CGAL::Predicate_leda_rat_less_xy_2::ev_leda_rat_point, \ *this, &geo_hull::less_xy_occurence); */ less_rotate_ccw_it = CGAL::attach(KRES::EVENT, *this, &geo_hull::less_rotate_ccw_occurence); less_xy_it = CGAL::attach(KRES::EVENT, *this, &geo_hull::less_xy_occurence); w.clear(); //w.set_redraw(new_redraw); input_set = &L; draw_points(); current_hull.clear(); pold = w.set_point_style(leda_disc_point); } void reset_visualization() { std::cout << "less_rotate_ccw_counter:" << less_rotate_ccw_counter << "\n"; std::cout << "less_xy_counter :" << less_xy_counter << "\n"; CGAL::detach(less_rotate_ccw_it); CGAL::detach(less_xy_it); w.set_point_style(pold); //w.set_redraw(GeoWin::redraw_geowin); } // -------------------------------------------------------------------------------------------------- void update(const std::list& L, std::list& Sl) { Sl.clear(); std::list out; //Kernel traits; K traits; init_visualization(L); CGAL::ch_jarvis(L.begin(),L.end(), std::back_inserter(out), traits); reset_visualization(); if( out.size() > 1 ) { Point pakt,prev,pstart; std::list::const_iterator it=out.begin(); prev= *it; pstart=prev; it++; for(; it != out.end(); ++it) { pakt= *it; Sl.push_back(Segment(prev,pakt)); prev=pakt; } Sl.push_back(Segment(pakt,pstart)); } } }; int main() { geowin_init_default_type((std::list*)0, leda_string("point")); std::list L; GeoWin GW("Jarvis march"); geo_hull update_obj(GW); geo_scene my_scene= GW.new_scene(L); geo_scene result = GW.new_scene(update_obj,my_scene,leda_string("Convex Hull")); GW.set_visible(result,true); GW.message("Giftwrapping - 1. phase: find point with minimal x-value, 2. phase: wrap the input point set"); GW.edit(my_scene); return 0; } #endif