File: minkowski.cpp

package info (click to toggle)
cgal 6.1.1-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 144,952 kB
  • sloc: cpp: 811,597; ansic: 208,576; sh: 493; python: 411; makefile: 286; javascript: 174
file content (133 lines) | stat: -rw-r--r-- 4,338 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// Copyright (c) 2005-2009  INRIA Sophia-Antipolis (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)     : 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)