mirror of https://github.com/CGAL/cgal
142 lines
4.7 KiB
C++
142 lines
4.7 KiB
C++
// Copyright (c) 2005-2009 INRIA Sophia-Antipolis (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) : Sebastien Loriot, Sylvain Pion
|
|
|
|
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
|
|
#include <CGAL/CGAL_Ipelet_base.h>
|
|
#include <CGAL/minkowski_sum_2.h>
|
|
#include <CGAL/approximated_offset_2.h>
|
|
#include <CGAL/offset_polygon_2.h>
|
|
|
|
|
|
|
|
namespace CGAL_minkowski{
|
|
|
|
typedef CGAL::Exact_predicates_exact_constructions_kernel Kernel;
|
|
typedef CGAL::Polygon_with_holes_2<Kernel,std::vector<Kernel::Point_2> > Polygon_with_holes_2;
|
|
typedef CGAL::Gps_circle_segment_traits_2<Kernel> Gps_traits_2;
|
|
typedef Gps_traits_2::Polygon_2 Offset_polygon_2;
|
|
typedef Gps_traits_2::Polygon_with_holes_2 Offset_polygon_with_holes_2;
|
|
|
|
|
|
const std::string Slab[] = {
|
|
"Minkowski Sum",
|
|
"Polygon Offset",
|
|
"Help"
|
|
};
|
|
|
|
const std::string Hmsg[] = {
|
|
"Compute the Minkowski sum of two simple polygons. Origin is placed at the min point of the bounding box of the selected objects",
|
|
"Compute the offsets of a simple polygon defined by a set of circles"
|
|
};
|
|
|
|
class SubSelectIpelet
|
|
: public CGAL::Ipelet_base<Kernel,3>{
|
|
public:
|
|
SubSelectIpelet()
|
|
:CGAL::Ipelet_base<Kernel,3>("Minkowski Sum",Slab,Hmsg){}
|
|
void protected_run(int);
|
|
};
|
|
|
|
|
|
void SubSelectIpelet::protected_run(int fn)
|
|
{
|
|
if (fn==2) {
|
|
show_help();
|
|
return;
|
|
}
|
|
|
|
std::list<Circle_2> cir_list;
|
|
std::list<Polygon_2> pol_list;
|
|
|
|
Iso_rectangle_2 bbox=
|
|
read_active_objects(
|
|
CGAL::dispatch_or_drop_output<Polygon_2,Circle_2>(
|
|
std::back_inserter(pol_list),
|
|
std::back_inserter(cir_list)
|
|
)
|
|
);
|
|
|
|
|
|
if (fn==0 && pol_list.size()!=2){
|
|
print_error_message("You must select exactly two polygons");
|
|
return;
|
|
}
|
|
|
|
|
|
std::list<double> r_offsets;
|
|
for (std::list<Circle_2>::iterator it=cir_list.begin();it!=cir_list.end();++it)
|
|
r_offsets.push_back(sqrt(CGAL::to_double(it->squared_radius())));
|
|
|
|
IpeMatrix tfm (1,0,0,1,-CGAL::to_double(bbox.min().x()),-CGAL::to_double(bbox.min().y()));
|
|
|
|
for (std::list<Polygon_2>::iterator it=pol_list.begin();it!=pol_list.end();++it)
|
|
if(!it->is_simple()){
|
|
print_error_message("Polygon(s) must be simple");
|
|
}
|
|
|
|
|
|
if (fn==0){
|
|
Polygon_2 polygon1=*pol_list.begin();
|
|
Polygon_2 polygon2=*++pol_list.begin();
|
|
Polygon_with_holes_2 sum = minkowski_sum_2 (polygon1, polygon2);
|
|
std::list<Point_2> LP;
|
|
for (Polygon_2::iterator it=sum.outer_boundary().vertices_begin();it!= sum.outer_boundary().vertices_end();++it)
|
|
LP.push_back(*it);
|
|
draw_polyline_in_ipe(LP.begin(),LP.end(),true,false,false);
|
|
|
|
for (Polygon_with_holes_2::Hole_const_iterator poly_it = sum.holes_begin(); poly_it != sum.holes_end();
|
|
++poly_it){
|
|
LP.clear();
|
|
for (Polygon_2::iterator it=poly_it->vertices_begin();it!= poly_it->vertices_end();++it)
|
|
LP.push_back(*it);
|
|
draw_polyline_in_ipe(LP.begin(),LP.end(),true,false,false);
|
|
}
|
|
|
|
create_polygon_with_holes(true);
|
|
transform_selected_objects_(tfm);
|
|
}
|
|
else{
|
|
if (r_offsets.size()==0)
|
|
r_offsets.push_back(10);
|
|
for (std::list<Polygon_2>::iterator it_pol=pol_list.begin();it_pol!=pol_list.end();++it_pol){
|
|
for(std::list<double>::iterator it=r_offsets.begin();it!=r_offsets.end();++it){
|
|
Offset_polygon_with_holes_2 offset=approximated_offset_2 (*it_pol, *it, 0.0001);
|
|
std::list<Segment_2> LS;
|
|
for( Offset_polygon_2::Curve_iterator itt=offset.outer_boundary().curves_begin();
|
|
itt!=offset.outer_boundary().curves_end();++itt){
|
|
Point_2 S=Point_2(CGAL::to_double(itt->source().x()),CGAL::to_double(itt->source().y()));
|
|
Point_2 T=Point_2(CGAL::to_double(itt->target().x()),CGAL::to_double(itt->target().y()));
|
|
if (itt->is_linear ())
|
|
LS.push_back(Segment_2(S,T));
|
|
if (itt->is_circular())
|
|
draw_in_ipe(Circular_arc_2(itt->supporting_circle(),S,T,itt->supporting_circle().orientation()));
|
|
}
|
|
draw_in_ipe(LS.begin(),LS.end());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
CGAL_IPELET(CGAL_minkowski::SubSelectIpelet)
|
|
|