summaryrefslogtreecommitdiffstats
path: root/rasodmg/polycutout.hh
blob: 435503b64f0118eda383066890d55cf797976a84 (plain)
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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
/*
* This file is part of rasdaman community.
*
* Rasdaman community is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Rasdaman community is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with rasdaman community.  If not, see <http://www.gnu.org/licenses/>.
*
* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
rasdaman GmbH.
*
* For more information please see <http://www.rasdaman.org>
* or contact Peter Baumann via <baumann@rasdaman.com>.
/
/**
 * INCLUDE: polycutout.hh
 *
 * MODULE:  rasodmg
 * CLASS:   r_PolygonCutOut
 *
 * COMMENTS:
 *
 * This class is intended to perform the polygon cut out operation
 * Except for the r_PolygonCutOut class, everything else is just 
 * for internal use
 * Attention: this version works good (I hope :-) but has just a tiny geometrical problem:
 *            as usual in discrete space, lines are build up by little horiontal segments.
 *	      Edges are considered to be inside, except the first little segment of a line.
 *	      This is only for avoiding a bigger problem, I will develop a better algorythm
*/

/*
  This module is intended to perform polygon cut out operation. It supports the exact ESRI specifications
  regarding "clean" polygons, this means: not self intersecting, closed, if you walk from an point to the 
  next of edge the inside is on the right. It also supports multiple rings, but the outer one has to have 
  the "inside" inside.
  Don't forget that the rasdaman coordinates are with x left->right and y top->down, or at least
  I have considered them so because of the usual coordinates of tiffs
*/

#ifndef _R_POLYGON_CUT_OUT_HH
#define _R_POLYGON_CUT_OUT_HH

#include <iosfwd>
#include <vector>
#include <list>
#include <string>
using std::string;
using std::list;
using std::vector;
using std::ostream;

#include "raslib/point.hh"
#include "raslib/minterval.hh"
#include "rasodmg/polygon.hh"


//@ManMemo: Module: {\bf rasodmg}


/**
  * \ingroup Rasodmgs
  */
class r_SegmentIterator
  {
   public:
     r_SegmentIterator(r_Point&,r_Point&);
     void reset();
     r_Point next();
     bool hasMore();
     int  cosFunc(); // limited use,1000 * cos(alfa)
   private:
     void  swap(r_Range&, r_Range&);
     r_Point createCurrentPoint();

     r_Point start;
     r_Point end;
     int cadran;

     r_Range dx,dy;
     r_Range cx,cy;
     int   beta;
   };

/**
  * \ingroup Rasodmgs
  */
class r_Line
  {
    public:
      r_Line();
      r_Line(double,double,double);
      r_Line(r_Point&,r_Point&);
      double getA();
      double getB();
      double getC();
      float ecuatia(r_Point&);
    private:
      double a,b,c;
    friend ostream& operator<<(ostream&,r_Line&);
   };


/**
  * \ingroup Rasodmgs
  */
class r_PolygonCutOut
  {
    public:
      r_PolygonCutOut();
      ~r_PolygonCutOut();
      void setImageSize(r_Range width, r_Range height);
      
      void setMArray(r_GMarray& myArray);
      void addPolygon(const r_Polygon&);
      
      bool fillMArrayInside(const string& bgr = "") throw(r_Error);
      bool fillMArrayOutside(const string& bgr = "") throw(r_Error);
      
      // just for debugging
      void print(int onlyLine=-1);
      void printLine(r_Range line);
      
    private:
      bool compute();
      void eraseLine( r_Range, r_Range, r_Range y, const string& bgr ) throw(r_Error);
     
      r_Range imgWidth,imgHeight;
      r_Range imgX,imgY; // - the origin of the mdd domain
     
      r_GMarray *mArray;
     
      std::list<r_Polygon> polygons;
     
      struct TablePoint
       { r_Range x;
	 int   inside; // where the inside is, -1 left, +1 right, 0 hor. line
	 int   cosFunc;
         bool operator==(TablePoint&);
	};

     r_Range tableWidth;
     r_Range tableHeight;
     TablePoint *table;
     int        *usedCount;
     TablePoint& getTP(r_Range line, r_Range column);
     
     bool initTable();
     void clearTables();
     int  computeTableWidth();

     
     int  computeInside(r_Point start, r_Point end);
     void computeOneSegment(r_Point start, r_Point end, int inside);
     void computeOneHorSegment(r_Point start, r_Point end);
     void ordonateLine(int line);
     void minimizeLine(int line);
     void replacePoint(r_Range line,r_Range col,int inside, int cosFunc);
     void addPoint(r_Range line,r_Range col,int inside, int cosFunc);

   };

#endif