1 //*****************************************************************************
2 // FILE: ossimPolygon.h
3 //
4 // Copyright (C) 2001 ImageLinks, Inc.
5 //
6 // License: MIT
7 //
8 // AUTHOR: Oscar Kramer
9 //
10 // DESCRIPTION: Contains declaration of class ossimPolygon.
11 //   This class provides utilities associated with N-vertex, convex
12 //   (i.e., only two intersections for any line passing through the polygon).
13 //
14 // LIMITATIONS: None.
15 //
16 //*****************************************************************************
17 //  $Id: ossimPolygon.h 22333 2013-07-26 15:55:36Z dlucas $
18 
19 #ifndef ossimPolygon_HEADER
20 #define ossimPolygon_HEADER 1
21 
22 #include <ossim/base/ossimDpt.h>
23 #include <ossim/base/ossimDrect.h>
24 #include <ossim/base/ossimIrect.h>
25 #include <iostream>
26 #include <vector>
27 class ossimLine;
28 
29 /******************************************************************************
30  *
31  * CLASS:  ossimPolygon
32  *
33  *****************************************************************************/
34 class OSSIMDLLEXPORT ossimPolygon
35 {
36 public:
37   typedef std::vector<ossimPolygon> Vector;
38    ossimPolygon();
39    ossimPolygon(const std::vector<ossimIpt>& polygon);
40    ossimPolygon(const std::vector<ossimDpt>& polygon);
41    ossimPolygon(const std::vector<ossimGpt>& polygon);
42    ossimPolygon(int numVertices, const ossimDpt* vertex_array);
43 
44    ossimPolygon(const ossimPolygon& copy_this);
45 
46    /**
47     * CONSTRUCTOR: Provided for convenience. Does not imply the polygon is
48     * limited to four vertices:
49     */
50    ossimPolygon(ossimDpt v1,
51                 ossimDpt v2,
52                 ossimDpt v3,
53                 ossimDpt v4);
54 
55    ossimPolygon(const ossimIrect& rect);
56    ossimPolygon(const ossimDrect& rect);
57 
58    ~ossimPolygon();
59 
60    ossimDpt& operator[](int index);
61 
62    const ossimDpt& operator[](int index)const;
63 
64    ossim_uint32 getVertexCount()const;
65 
66    ossim_uint32 getNumberOfVertices()const;
67 
68    //! Returns polygon area. Negative indicates CW ordering of vertices (in right-handed coordinates)
69    double area()const;
70 
71    void getIntegerBounds(ossim_int32& minX,
72                          ossim_int32& minY,
73                          ossim_int32& maxX,
74                          ossim_int32& maxY)const;
75    void getFloatBounds(ossim_float64& minX,
76                        ossim_float64& minY,
77                        ossim_float64& maxX,
78                        ossim_float64& maxY)const;
79 
80    /**
81     * @brief Gets the min and max of points.
82     *
83     * Points will be NAN in polygon is empty.
84     *
85     * @param min Initialized by this.
86     * @param max Initialized by this.
87     */
88    void getMinMax( ossimDpt& min, ossimDpt& max) const;
89 
90    void getBoundingRect(ossimIrect& rect)const;
91    void getBoundingRect(ossimDrect& rect)const;
92 
93    /**
94     * Initializes minRect with the minimum area rect (not-necessarily
95     * aligned with axes) that bounds this polygon.
96     *
97     * @param minRect Polygon to initialize with the minimum rect.
98     */
99    void getMinimumBoundingRect(ossimPolygon& minRect) const;
100 
101    void roundToIntegerBounds(bool compress=false);
102 
103    void clear();
104 
105    void addPoint(const ossimDpt& pt);
106    void addPoint(double x, double y);
107 
108    ossimDpt midPoint()const;
109 
110    /**
111     * will sequence through the polygon and check to see if any values are NAN
112     */
113    bool hasNans()const;
114 
115    const std::vector<ossimDpt>& getVertexList()const;
116 
117    /**
118     * Uses the ossimPolyArea2d class for the intersection
119     */
120    bool clipToRect(std::vector<ossimPolygon>& result,
121                    const ossimDrect& rect)const;
122 
123 
124    /**
125     * METHOD: clipLineSegment(p1, p2)
126     * Implements Cyrus-Beck clipping algorithm as described in:
127     * http://www.daimi.au.dk/~mbl/cgcourse/wiki/cyrus-beck_line-clipping_.html
128     * Clips the line segment defined by thw two endpoints provided. The
129     * endpoints are modified as needed to represent the clipped line. Returnes
130     * true if intersection present.
131     */
132    bool clipLineSegment(ossimDpt& p1, ossimDpt& p2) const;
133 
134    /**
135     * METHOD: pointWithin(ossimDpt)
136     * Returns TRUE if point is inside polygon.
137     */
138    bool pointWithin(const ossimDpt& point) const;
139 
140    bool isPointWithin(const ossimDpt& point) const;
141 
142    /**
143    * METHOD: isRectWithin()
144    * Returns true if all the corner points of the given rect fit within.
145    */
146    bool isRectWithin(const ossimIrect &rect) const;
147 
148    /**
149    * METHOD: rectIntersects()
150    * Returns true if at least one corner points of the given rect is within.
151    */
152    bool rectIntersects(const ossimIrect &rect) const;
153 
154    /**
155    * METHOD: isPolyWithin()
156    * Returns true if all the vertices of the given polygon fit within.
157    */
158    bool isPolyWithin(const ossimPolygon &poly) const;
159 
160 /**
161     * METHOD: vertex(index)
162     * Returns the ossimDpt vertex given the index. Returns false if no vertex
163     * defined.
164     */
165    bool vertex(int index, ossimDpt& tbd_vertex) const;
166 
167    /**
168     * METHOD: nextVertex()
169     * Assigns the ossimDpt tbd_vertex following the current vertex. The current
170     * vertex is initialized with a call to vertex(int), or after the last
171     * vertex is reached. Returns false if no vertex defined. Intended to be
172     * when cycling through all vertices.
173     */
174    bool nextVertex(ossimDpt& tbd_vertex) const;
175 
176    void reverseOrder();
177    /**
178     * OPERATORS: (Some are inlined at bottom)
179     */
180    const ossimPolygon& operator= (const ossimPolygon& copy_this);
181    const ossimPolygon& operator= (const std::vector<ossimDpt>& vertexList);
182    const ossimPolygon& operator= (const std::vector<ossimGpt>& vertexList);
183    const ossimPolygon& operator= (const std::vector<ossimIpt>& vertexList);
184    const ossimPolygon& operator= (const ossimIrect& rect);
185    const ossimPolygon& operator= (const ossimDrect& rect);
186    bool                operator==(const ossimPolygon& compare_this) const;
187    bool                operator!=(const ossimPolygon& compare_this) const;
188 
189    const ossimPolygon& operator *=(const ossimDpt& scale);
190    const ossimPolygon& operator *=(double scale);
191 
192    ossimPolygon operator *(const ossimDpt& scale)const;
193    ossimPolygon operator *(double scale)const;
194 
195    void resize(ossim_uint32 newSize);
196 
197    /**
198     * METHOD: removeVertex()
199     * Removes the vertex from the polygon.
200     */
201    void removeVertex(int vertex);
202 
203    /**
204     * METHOD: print()
205     */
206    void print(std::ostream& os) const;
207    friend std::ostream& operator<<(std::ostream&, const ossimPolygon&);
208 
209 
210    bool saveState(ossimKeywordlist& kwl,
211                   const char* prefix=0)const;
212 
213    bool loadState(const ossimKeywordlist& kwl,
214                   const char* prefix=0);
215 
216    ossimVertexOrdering checkOrdering()const;
217 
218    ossimVertexOrdering getOrdering()const;
219 
220 protected:
221    /**
222    * METHOD: getCentroid()
223    * Assigns the ossimDpt centroid the polygon.
224    * Warning: centroid is not guaranteed to be inside the polygon!
225     */
226    void getCentroid(ossimDpt &centroid) const;
227 
228    /**
229    * METHOD: shrink()
230    * Shrinks the current polygon by inset, return true if success.
231     */
232    bool shrink(ossimPolygon &dest, double inset) const;
233 
234    /**
235     * METHOD: removeSmallestContributingVertex()
236     * Removes the vertex that contributes the smallest area to the polygon.
237     */
238    void removeSmallestContributingVertex();
239 
240    void intersectEdge(ossimDpt& result,
241                       const ossimLine& segment,
242                       const ossimDrect& rect,
243                       int edge);
244 
245    bool isInsideEdge(const ossimDpt& pt,
246                      const ossimDrect& rect,
247                      int edge)const;
248 
249    /**
250    * Assigns destPt the point that fits a circle of given radius inside the polygon vertex.
251    * Warning: destPt is not guaranteed to be inside the polygon!
252    * (you may not be able to fit a circle of the given radius inside the polygon)
253    */
254    void fitCircleInsideVertex(ossimDpt &destPt, unsigned int vertex, double radius) const;
255 
256    mutable ossimVertexOrdering theOrderingType;
257    std::vector<ossimDpt> theVertexList;
258    mutable ossim_int32 theCurrentVertex;
259 };
260 
261 #endif /* End of "#ifndef ossimPolygon_HEADER" */
262