cgal/Leda_rat_kernel/demo/leda_traits/jarvis_anim_special.C

210 lines
6.2 KiB
C

/*
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 <CGAL/basic.h>
#if !defined(CGAL_USE_LEDA) || (__LEDA__ < 420)
#include <iostream>
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 <CGAL/Cartesian.h>
#include <CGAL/leda_rational.h>
#include <CGAL/Kernel_special.h>
#include <CGAL/kernel_event_support.h>
#include <CEP/Leda_rat_kernel/leda_rat_kernel_traits.h>
#include <CEP/Leda_rat_kernel/geowin_leda_rat_kernel.h>
#include <CGAL/ch_selected_extreme_points_2.h>
#include <CGAL/ch_jarvis.h>
#include <CGAL/geowin_support.h>
#if defined(LEDA_NAMESPACE)
using namespace leda;
#endif
typedef CGAL::leda_rat_kernel_traits LEDA_KERNEL;
typedef CGAL::kernel_event<LEDA_KERNEL> KEV;
typedef CGAL::kernel_event<int> KRES;
typedef CGAL::Kernel_special<LEDA_KERNEL, KEV, KRES> 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<Point>, std::list<Segment> >
{
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<Point> current_hull;
leda_point_style pold;
const std::list<Point>* 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<Point>::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<Point>::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<Point>& 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<K>::ev_leda_rat_point, \
*this, &geo_hull::less_rotate_ccw_occurence);
less_xy_it = CGAL::attach(CGAL::Predicate_leda_rat_less_xy_2<K>::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<Point>& L, std::list<Segment>& Sl)
{
Sl.clear();
std::list<Point> 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<Point>::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<Point>*)0, leda_string("point"));
std::list<Point> 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