polyline_arr_from_mouse.c
来自「CGAL is a collaborative effort of severa」· C语言 代码 · 共 253 行
C
253 行
// demo/Arrangement_2/Polyline_arr_from_mouse.C//// constructs an arrangement of polylines from user input// We use the leda traits (therefore we use leda functions).#include "short_names.h"#include <CGAL/basic.h>#ifndef CGAL_USE_LEDA#include <iostream>int main(){ std::cout << "Sorry, this demo needs LEDA for visualisation."; std::cout << std::endl; return 0;}#else#include <CGAL/Cartesian.h>#include <CGAL/MP_Float.h>#include <CGAL/Quotient.h>#include <CGAL/Arrangement_2.h>#include <CGAL/Arr_2_bases.h>#include <CGAL/Arr_2_default_dcel.h>#include <CGAL/Arr_segment_cached_traits_2.h>#include <CGAL/Arr_polyline_traits_2.h>#include <LEDA/string.h>#include <CGAL/Draw_preferences.h>#include <vector>typedef CGAL::Quotient<CGAL::MP_Float> NT;typedef CGAL::Cartesian<NT> Kernel;typedef CGAL::Arr_segment_cached_traits_2<Kernel> Seg_traits;typedef CGAL::Arr_polyline_traits_2<Seg_traits> Traits;typedef Traits::Point_2 Point_2;typedef Traits::X_monotone_curve_2 X_monotone_curve_2;typedef Traits::Curve_2 Curve_2;typedef CGAL::Arr_base_node<Curve_2, X_monotone_curve_2> Base_node;typedef CGAL::Arr_2_default_dcel<Traits> Dcel;typedef CGAL::Arrangement_2<Dcel,Traits,Base_node > Arr_2;// global variables are used so that the redraw function for the LEDA window// can be defined to draw information found in these variables.static Arr_2 Arr; static leda_string text("");static std::vector<Point_2> pts;CGAL_BEGIN_NAMESPACE// Draw a polyline.Window_stream& operator<< (Window_stream& os, const X_monotone_curve_2& cv){ X_monotone_curve_2::const_iterator ps = cv.begin(); X_monotone_curve_2::const_iterator pt = ps; pt++; while (pt != cv.end()) { os << Kernel::Segment_2(*ps, *pt); ps++; pt++; } return (os);}Window_stream & operator<<(Window_stream & os, Arr_2 & arr){ My_Arr_drawer<Arr_2, Arr_2::Ccb_halfedge_circulator, Arr_2::Holes_iterator> drawer(os); draw_pm(arr, drawer, os); return os;}CGAL_END_NAMESPACEvoid show_welcome_message(CGAL::Window_stream & os){ text += "\\black "; text += "Click left button for polyline points.\\n "; text += "Click right button as last point in polygon.\\n "; text += " \\n "; text += "Clicking close to a point, assumes the location is at the point.\\n "; text += "Isolated points will be discarded.\\n "; os.set_status_string("Press Begin to enter polylines."); os.redraw(); // wait for button}// redraw function for LEDA window. used automatically when window reappearsvoid redraw(CGAL::Window_stream * wp) { wp->start_buffering(); wp->clear(); // display message if one exists if (text) wp->text_box(text); // draw currently inserted polyline *wp << CGAL::BLACK; if (pts.size() > 1) *wp << Curve_2(pts.begin(), pts.end()); else if (pts.size() == 1) *wp << pts[0]; // draw arragnement *wp << Arr; wp->flush_buffer(); wp->stop_buffering();}int main(){ // window settings double x0=-400,x1=400,y0=-400; enum { THE_BUTTON = 10 }; CGAL::Window_stream W(400, 400, "CGAL - 2D Polyline Arrangement Demo"); W.init(x0,x1,y0); W.set_redraw(redraw); W.set_mode(CGAL_LEDA_SCOPE::src_mode); W.set_node_width(3); W.button(" Begin ",THE_BUTTON); W.open_status_window(); W.display(leda_window::center,leda_window::center); // (1) welcome part show_welcome_message(W); while (W.read_mouse() != THE_BUTTON); text = ""; // empty message for redraw W.clear(); W.set_status_string("Left - points. " "Right - last point. Continue - point location"); // (2) polylines insertion part Point_2 pnt, last_pnt; bool should_exit = false, first_point = true; double x, y; // doubles are used to read off screen, but not in computations int b; // button W.set_button_label(THE_BUTTON, "Continue"); while (! should_exit) { b = W.read_mouse(x,y); last_pnt = pnt; pnt = Point_2(x,y); if (b == THE_BUTTON) should_exit = true; else if (b == MOUSE_BUTTON(1) || MOUSE_BUTTON(3)) { // looking for points in the vicinity of the click bool vicinity_point = false, last_in_polyline = false; // first, looking in the points of this polyline std::vector<Point_2>::const_iterator cit = pts.begin(); for(; ! vicinity_point && cit != pts.end(); cit++) { if (CGAL::squared_distance(pnt, *cit) < NT(((x1-x0)/50)*((x1-x0)/50))) { pnt =* cit; vicinity_point = true; } } // check if last point was re-clicked if ( vicinity_point && last_pnt == pnt ) { last_in_polyline = true; } // second, looking in other points of the arrangement for(Arr_2::Vertex_iterator vi = Arr.vertices_begin(); ! vicinity_point && vi != Arr.vertices_end(); ++vi) { if (CGAL::squared_distance(pnt, vi->point()) < NT(((x1-x0)/50)*((x1-x0)/50))) { pnt = vi->point(); vicinity_point = true; } } // if last point was re-clicked ignore to avoid invalidity of polyline. if ( ! last_in_polyline ) pts.push_back(pnt); W << CGAL::BLACK; W << pnt; if (!first_point) { W << Kernel::Segment_2(last_pnt, pnt); // W <<leda_segment(last_pnt.x().to_double(), last_pnt.y().to_double(), // pnt.x().to_double(), pnt.y().to_double()); } first_point = false; } // end of polyline // on right click, or on "Continue" if (b == MOUSE_BUTTON(3) || (should_exit && pts.size() > 1)) { if ( pts.size() > 1) //(at least 2 points, otherwise ignore) Arr.insert(Curve_2(pts.begin(), pts.end())); pts.clear(); W << Arr; first_point = true; } } W.redraw(); // (3) Point Location part Arr_2::Halfedge_handle e; bool map_is_empty = false; if (Arr.halfedges_begin() == Arr.halfedges_end()) map_is_empty = true; if (map_is_empty) { W.set_status_string("Arrangement is empty. Press Quit to quit."); } else { W.set_status_string("Enter a point with left button. Press Quit to quit."); } W.set_button_label(THE_BUTTON, " Quit "); //enable_button(THE_BUTTON); while (W.read_mouse(x,y) != THE_BUTTON) { pnt = Point_2(x, y); W << Arr; if ( ! map_is_empty ) { Arr_2::Locate_type lt; e = Arr.locate(pnt ,lt); // color the face on the screen W << CGAL::GREEN; Arr_2::Face_handle f=e->face(); if (f->does_outer_ccb_exist()) { Arr_2::Ccb_halfedge_circulator cc=f->outer_ccb(); do { W << cc->curve(); } while (++cc != f->outer_ccb()); } for (Arr_2::Holes_iterator ho=f->holes_begin(),hoe = f->holes_end(); ho != hoe; ++ho) { Arr_2::Ccb_halfedge_circulator cc = *ho; do { W << cc->curve(); } while (++cc != *ho); } } // if ! map_is_empty } // while return 0; }#endif
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?