// Copyright (c) 2013 INRIA Sophia Antipolis - Mediterranee (France). // All rights reserved. // // This file is part of CGAL (www.cgal.org) // // $URL$ // $Id$ // SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial // // // Author(s) : Olivier Devillers #include #include #include #include "include/CGAL_ipelets/pencils.h" namespace CGAL_pencils{ typedef CGAL::Cartesian Kernel; // -------------------------------------------------------------------- const std::string sublabel[] = { "Circle in pencil, orthogonal to circle", "Circle orthogonal to three circles", "Help" }; const std::string helpmsg[] = { "Draw the circle orthogonal to a circle (primary selection) in the pencil generated by two circles", "Draw the circle orthogonal to three circles" }; class pencilIpelet : public CGAL::Ipelet_base { public: pencilIpelet() :CGAL::Ipelet_base("Pencils of circles",sublabel,helpmsg){} void protected_run(int); }; // -------------------------------------------------------------------- void pencilIpelet::protected_run(int fn) { Circle_2 circ; //constructed circle: if (fn==2) { show_help(); return; } Circle_2 c,c0,c1,c2; std::list pt_list,pt_list1; std::list cir_list,cir_list1; int i=get_IpePage()->primarySelection(); if (i<0) { print_error_message(("No mark or circle selected")); return; } read_one_active_object(get_IpePage()->object(i),CGAL::dispatch_or_drop_output( std::back_inserter(pt_list1), std::back_inserter(cir_list1))); std::list::iterator it1=pt_list1.begin(); std::list::iterator cit1=cir_list1.begin(); if (pt_list1.empty() && cir_list1.empty()){ print_error_message(("Primary selection must be a mark or a circle")); return; } if (it1!=pt_list1.end()) {c=Circle_2(*it1,0);} else c=*cit1; Iso_rectangle_2 bbox= read_active_objects( CGAL::dispatch_or_drop_output( std::back_inserter(pt_list), std::back_inserter(cir_list) ) ); std::list::iterator it=pt_list.begin(); std::list::iterator cit=cir_list.begin(); // read c0 if (it!=pt_list.end()) { c0=Circle_2(*it,0); ++it;} else if (cit!=cir_list.end()) { c0=*cit; ++cit;} else {print_error_message(("Not enough marks or circles selected")); return;} // read c1 if (it!=pt_list.end()) { c1=Circle_2(*it,0); ++it;} else if (cit!=cir_list.end()) { c1=*cit; ++cit;} else {print_error_message(("Not enough marks or circles selected")); return;} // read c2 if (it!=pt_list.end()) { c2=Circle_2(*it,0); ++it;} else if (cit!=cir_list.end()) { c2=*cit; ++cit;} else {print_error_message(("Not enough marks or circles selected")); return;} if ((it!=pt_list.end())||(cit!=cir_list.end())) {print_error_message(("Warning: more than three marks or circles selected"));} // c is the primary selection if (c==c1) c1=c0; if (c==c2) c2=c0; switch(fn){ case 0: // Circle orthogonal to circle c in pencil generated by c1 c2 circ = compute_circle_in_pencil(c,c1,c2); break; case 1: // Circle orthogonal to three circles circ = compute_circle_orthogonal(c,c1,c2); break; } //end of switch // detect degenerate case if (circ==Circle_2()){ Kernel::Vector_2 v; if(fn==0) v=Kernel::Vector_2( c2.center().y()-c1.center().y(),c2.center().x()-c1.center().x()); else v=c2.center()-c1.center(); Kernel::FT sqr_length= 1 / v.squared_length(); double length = 600 * sqrt( sqr_length); v = Kernel::FT(length)*v; Point_2 q1=c.center()+ v; Point_2 q2=c.center()- v; print_error_message( "degenerate case, circle is a line"); Kernel::Segment_2 s(q1,q2); draw_in_ipe(s); return; } if (circ.squared_radius()>0){ draw_in_ipe(circ); }else{ print_error_message(("Computed circle is imaginary")); } } } CGAL_IPELET(CGAL_pencils::pencilIpelet)