rasdaman complete source
polygon.hh
Go to the documentation of this file.
1 /*
2 * This file is part of rasdaman community.
3 *
4 * Rasdaman community is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * Rasdaman community is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
18 rasdaman GmbH.
19 *
20 * For more information please see <http://www.rasdaman.org>
21 * or contact Peter Baumann via <baumann@rasdaman.com>.
22 /
33 #ifndef _R_POLYGON_
34 #define _R_POLYGON_
35 
36 #include <iostream>
37 #include <vector>
38 #include <string>
39 
40 #include "raslib/point.hh"
41 #include "raslib/minterval.hh"
42 
43 class r_GMarray;
44 
45 //@ManMemo: Module: {\bf rasodmg}
46 
47 /*@Doc:
48 
49  The class r_Edge is used to represent edges of 2-D polygons
50  represented in class r_Polygon. Edges cannot be modified. This does
51  not make sense, as a polygon always has to consist out of connecting
52  edges. Modifications should always be done on the polygon.
53 
54 */
55 
59 class r_Edge
60 {
61 public:
63  r_Edge(const r_Point& newStart, const r_Point& newEnd);
64 
66  const r_Point& getStart() const;
67 
69  const r_Point& getEnd() const;
70 
72  double getInvSlope() const;
73 
75  double getSlope() const;
76 
78  double getCurrX(r_Range y) const;
79 
81  double getCurrY(r_Range x) const;
82 
84  void print_status( std::ostream& s = std::cout ) const;
85 
87  bool isHorizontal() const;
88 
89 private:
91  r_Point start;
92 
94  r_Point end;
95 };
96 
97 /*@Doc:
98 
99  The class r_Polygon is used to represent 2-D polygons in
100  RasDaMan. Polygons are always constructed by specifying a set of
101  points. This class is mainly used for doing polygonal cutouts on
102  r_Marray objects, it offers the relevant methods for that purpose.
103 
104  The construction of a r_Polygon with addPoint has to finish with a
105  call to close(). A open polygon is not a legal polygon! Currently no
106  exceptions are thrown if a polygon is open and methods besides
107  addPointXY or close are called. The results are undefined, if the
108  polygon is not closed.
109 
110 */
111 
115 class r_Polygon
116 {
117 public:
118 
120  static const r_Dimension polyPointDim;
121 
123  enum r_Polygon_Type
124  {
125  UNKNOWN,
126  CONCAVE,
127  CONVEX
128  };
129 
131  r_Polygon(const char* init) throw (r_Error);
132 
134  r_Polygon(r_Range x, r_Range y);
135 
137  r_Polygon(const r_Polygon&);
138 
140  r_Polygon();
141 
143  r_Polygon& operator=(const r_Polygon&);
144 
146  void addPoint(const r_Point& newPoint) throw(r_Error);
147 
149  void addPointXY(r_Range x, r_Range y) throw(r_Error);
150 
152  void close();
153 
155  const std::vector<r_Edge>& getEdges() const throw(r_Error);
156 
158  r_Polygon::r_Polygon_Type detectPolygonType() const throw(r_Error);
164  std::vector<r_Point> getPoints() const throw(r_Error);
170  void print_status( std::ostream& s = std::cout ) const;
172 
174  void fillMArray( r_GMarray& myArray, bool fillInside = false, const std::string& bgr = "") const throw(r_Error);
181  r_Minterval getBoundingBox() const throw(r_Error);
183 
185  void clip(const r_Minterval& clipDom) throw(r_Error);
189  void scale(const r_Point& origin, const r_Minterval& mddDom,
191  const r_Minterval& clipDom, const double& scaleFactor) throw(r_Error);
202  void scale(const r_Point& origin, const double& scaleFactor) throw(r_Error);
208  void mirror(const r_Minterval& mddDom) throw(r_Error);
213  r_Point getMiddle() const throw(r_Error);
215 
217  void shrinkPoly(int pixelCount) throw(r_Error);
218 
220  int countEdges() const;
221 
223  int countHorizontalEdges() const;
224 
225 private:
226 
228  void checkFistPoint();
229 
231  enum Side
232  {
233  top, bottom, left, right
234  };
235 
237  void fromPoints(const std::vector<r_Point>& newPoints) throw(r_Error);
238 
240  void eraseLine( r_Range x1, r_Range x2, r_Range y, r_GMarray& myArray, const std::string& bgr ) const throw(r_Error);
241 
243  std::vector<r_Point> clip1Side(const r_Minterval& b, r_Polygon::Side s);
244 
246  bool inside(const r_Minterval& b, const r_Point& p, r_Polygon::Side s);
247 
249  r_Point intersect(const r_Minterval& b, const r_Edge& e, r_Polygon::Side s);
250 
252  bool closed;
253 
255  bool firstPointSet;
256 
258  std::vector<r_Edge> edges;
260 
261  r_Point firstPoint;
262 
264  r_Point currPoint;
265 };
266 
267 extern std::ostream& operator<<( std::ostream& s, const r_Polygon& d );
268 
269 // The following classes are STL function objects which can be used to make
270 // sorted collection of r_Edge. In the current implementation only the first
271 // one is needed.
272 
276 class EdgeSortCriterion
277 {
278 public:
279  // This is needed for keeping a sorted set of edges (sorted by start coordinate y,
280  // then start coordinate x).
281  bool operator() (const r_Edge& e1, const r_Edge& e2) const
282  {
283  return e1.getStart()[1] < e2.getStart()[1] ||
284  (!(e2.getStart()[1] < e1.getStart()[1]) && e1.getStart()[0] < e2.getStart()[0]);
285  }
286 };
287 
291 class ActiveEdgeSortCriterion
292 {
293 public:
294  // This is needed for keeping a sorted set of active edges (sorted by start coordinate x,
295  // then start coordinate y).
296  bool operator() (const r_Edge& e1, const r_Edge& e2) const
297  {
298  return e1.getStart()[0] < e2.getStart()[0] ||
299  (!(e2.getStart()[0] < e1.getStart()[0]) && e1.getStart()[1] < e2.getStart()[1]);
300  }
301 };
302 
303 #endif
#define false
Definition: bool.h:23
#define UNKNOWN
Definition: oql.h:310
template std::ostream & operator<<(const vector< KeyObject > &, std::ostream &)