cgal/CGAL_ipelets/demo/CGAL_ipelets/circle_pencils.cpp

158 lines
4.5 KiB
C++

// Copyright (c) 2013 INRIA Sophia Antipolis - Mediterranee (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 3 of the License,
// or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
//
//
// Author(s) : Olivier Devillers
#include <CGAL/Cartesian.h>
#include <CGAL/CGAL_Ipelet_base.h>
#include <CGAL/Object.h>
#include "include/CGAL_ipelets/pencils.h"
namespace CGAL_pencils{
typedef CGAL::Cartesian<double> 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<Kernel,3> {
public:
pencilIpelet()
:CGAL::Ipelet_base<Kernel,3>("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<Point_2> pt_list,pt_list1;
std::list<Circle_2> 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<Point_2,Circle_2>(
std::back_inserter(pt_list1),
std::back_inserter(cir_list1)));
std::list<Point_2>::iterator it1=pt_list1.begin();
std::list<Circle_2>::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<Point_2,Circle_2>(
std::back_inserter(pt_list),
std::back_inserter(cir_list)
)
);
std::list<Point_2>::iterator it=pt_list.begin();
std::list<Circle_2>::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<Kernel>(c,c1,c2);
break;
case 1:
// Circle orthogonal to three circles
circ = compute_circle_orthogonal<Kernel>(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)