Overture  Version 25
QuadTree.h
Go to the documentation of this file.
1 #ifndef QUADTREE_H
2 #define QUADTREE_H
3 
4 #include "TrimmedMapping.h"
5 
6 class TMcurves
7 // curve and segment index data for quadtree calculations for a TrimmedMapping.
8 // The indexing is be the same as for the Trimmed Mapping object used; i.e.
9 // the outer curve is 1 and the inner curves are 2,3...numberOfInnerCurves+1
10 // Their segments are numbered beginning at 0.
11 {
12 public:
13  const real& curveDist() const { return cdist; };
14  real& curveDist() { return cdist; };
15  const int& curvestart() const { return cstart; };
16  const int& curvestop() const { return cstop; };
17  int& curvestart() { return cstart; };
18  int& curvestop() { return cstop; };
19  const int& nodestart( const int c ) const { return nstart[c]; };
20  const int& nodestop( const int c ) const { return nstop[c]; };
21  int& nodestart( const int c ) { return nstart[c]; };
22  int& nodestop( const int c ) { return nstop[c]; };
23 
24 #ifdef OLDSTUFF
25  TMcurves( TrimmedMapping& tm, const int curvemin=1,
26 #else
27  TMcurves( TrimmedMapping& tm, const int curvemin=0,
28 #endif
29  const int curvemax=-1 ) :
30  cstart(curvemin), cstop(curvemax)
31  {
32  int c;
33  cdist = 0;
34 #ifdef OLDSTUFF
35  if ( curvemax==-1 ) cstop = tm.getNumberOfInnerCurves()+2;
36 #else
37  if ( curvemax==-1 ) cstop = tm.getNumberOfTrimCurves();
38 #endif
39  nstart = new int[cstop];
40  nstop = new int[cstop];
41 #ifdef OLDSTUFF
42  assert(cstart>=1);
44 #else
45  assert(cstart>=0);
46  assert(cstop<tm.getNumberOfTrimCurves()+1);
47 #endif
48  for ( c=cstart; c<cstop; ++c ) {
49  nstart[c] = 0;
50  nstop[c] = (tm.rCurve[c]).getLength(0)-1;
51  }
52  };
53  TMcurves() : cdist(0), cstart(0), cstop(0), nstart(0), nstop(0) {};
54 
55  TMcurves( const TMcurves& tmc )
56  { // deep copy
57  int c;
58  cdist = tmc.cdist;
59  cstart = tmc.cstart; cstop = tmc.cstop;
60  // delete[] nstart; delete[] nstop; // *wdh* 081210 -- these could not have been set yet
61  nstart = new int[cstop];
62  nstop = new int[cstop];
63  for ( c=cstart; c<cstop; ++c ) {
64  nstart[c] = tmc.nstart[c];
65  nstop[c] = tmc.nstop[c];
66  }
67  };
68 
69  TMcurves& operator=( const TMcurves& tmc )
70  {
71  int c;
72  cdist = tmc.cdist;
73  cstart = tmc.cstart; cstop = tmc.cstop;
74  delete[] nstart; delete[] nstop;
75  nstart = new int[cstop];
76  nstop = new int[cstop];
77  for ( c=cstart; c<cstop; ++c ) {
78  nstart[c] = tmc.nstart[c];
79  nstop[c] = tmc.nstop[c];
80  }
81  return *this;
82  };
83 
85  {
86  delete[] nstart;
87  delete[] nstop;
88  };
89 
90 protected:
91  real cdist; // cdist = lower bound for distance from square to curve cstart
92  int cstart;
93  int cstop;
94  int* nstart;
95  int* nstop;
96 };
97 
98 class TMquad
99 // A quadtree for use in trimmed mapping computations.
100 // This has data for one node of the tree, a square, and contains
101 // its four child squares, if any.
102 // Squares and corners are numbered: 0 1
103 // 2 3
104 {
105 protected:
106  static int maxsquares; // total number of squares made, over all quadtree meshes
107  static int nextID; // next ID number to use, when accumulating data in an array
109  // ... width of smallest square (2*dx), over all quadtree meshes; used only as a diagnostic
110 
111  real centerX; // a better style would be to use a class Point
113  real dx; // width of a child square
114  TMquad * children; // length 4, or NULL
115 
116  // The following data can principal be deleted for all but the leaf nodes
117  // and one level above the leaf nodes:
118  int inside; // 1 if this square (including border) is inside the
119  // trimmed region, -1 if outside, 0 if mixed or unknown
120  TMcurves curves; // lists all curves and their segments which may be relevent
121  // to insideness calculation for this square and its descendants.
122  // ... for leaf nodes there will only usually be no curves, or one line segment
123  // of one polygonal curve, or one segment from each of two intersecting curves;
124  // sometimes more curves if we don't resolve the quadtree far enough
125 
126  void remake( TrimmedMapping& tm, const real& centerX, const real& centerY,
127  const real& dx_, TMcurves& curves_ );
128 
129 public:
130  // Variables to control stopping the subdivision process.
131  // There is no point in using access functions because anything setting them
132  // needs to understand the algorithm anyway...
133  // Note: it would be a bit better to make dxMinNormal,dxMin2Curve serve as (user-
134  // resettable) default values which can be overridden by optional arguments of divide
136  // ... A square with smaller dx will not normally be subdivided
138  // ... A square with smaller dx will not be subdivided even if two
139  // curves pass through it. dxMin2Curve <= dxMinNormal
140 
141  int totalNumberSquaresMade() const { return maxsquares; };
142  int maxSquares() const { return maxsquares; };
144  const real& the_dx() const { return dx; };
145  const real& the_centerX() const { return centerX; };
146  const real& the_centerY() const { return centerY; };
147  int the_inside() const { return inside; };
148  const TMcurves& the_curves() const { return curves; };
149 
150  bool insideSquare( const real x, const real y,
151  const real x0, const real x1, const real y0, const real y1 ) const {
152  if ( x>=x0 && x<=x1 && y>=y0 && y<=y1 ) {
153  return true; }
154  else {
155  return false; }
156  };
157  TMquad();
158  TMquad( TrimmedMapping& tm, const real& centerX_, const real& centerY_,
159  const real dx_ );
160  TMquad& operator=( const TMquad& tmq ) {
161  // deep copy
162  centerX = tmq.centerX;
163  centerY = tmq.centerY;
164  dx = tmq.dx;
165  inside = tmq.inside;
166  if ( children != NULL ) delete[] children;
167  if ( tmq.children == NULL ) {
168  children = NULL;
169  }
170  else {
171  children = new TMquad[4];
172  for ( int i=0; i<4; ++i ) children[i] = tmq.children[i];
173  };
174  curves = tmq.curves;
175  return *this;
176  };
178  delete[] children;
179  };
180 
182  real x0, real y0, real u0, real v0 ) const;
183  real distanceBetweenSegments( real x1, real y1, real u1, real v1,
184  real x2, real y2, real u2, real v2 ) const;
185  real distanceToCurve( int c, TrimmedMapping& tm ) const;
186 
187  void divide( TrimmedMapping& tm, int& sizeOfMesh, real& minWidth );
188 // void plot( PlotStuff & gi, PlotStuffParameters parameters ) const;
189  void plot( GenericGraphicsInterface & gi, GraphicsParameters parameters ) const;
191  const int startID = nextID ) const;
193  const int startID = nextID ) const;
194  // const TMquad& squareItsIn( Point pt ); ... the way I'd like to do it
195  const TMquad* squareItsIn( real pointX, real pointY ) const;
196  const TMquad* squareItsIn( real pointX, real pointY, TMquad*& parent ) const;
197  bool inThisSquare( real pointX, real pointY ) const;
198 
199  // put and get functions: put a description of this quadtree into a database
200  // file, and get it out. There is not a standard virtual get function because
201  // TMquad is not an independent object; it belongs to a TrimmedMapping.
202  // Note: More compact and faster would be to save just the minimal information:
203  // that is the centerX,centerY,dx for only those squares on which divide was
204  // called (at the top level); with the divide parameters for each such call;
205  // and of course the static variables. That would require programming complexities
206  // such as another class; so for now we save the entire tree (i.e.,
207  // centerX,centerY,dx,and children for each square) but recompute insideness
208  // information rather than saving it.
209  int TMget( const GenericDataBase & dir, const aString & name,
210  TrimmedMapping& tm, TMcurves * curves_ = NULL );
211  virtual int put( GenericDataBase & dir, const aString & name) const;
212  void getStatics( GenericDataBase & dir ) const;
213  void putStatics( GenericDataBase & dir ) const;
214 
215 private:
216  TMquad( const TMquad& tmq ) { cerr << "TMquad copy constructor call unexpected" << endl; };
217 
218 };
219 
220 class TMquadRoot : public TMquad
221 // A special version of TMquad for the root square of a quadtree mesh.
222 // The only difference is that a TMquadRoot knows some control
223 // parameters (not yet) and diagnostic indicators.
224 {
225 public:
226  int sizeOfQuadTreeMesh; // for diagnostics
227  real minQuadTreeMeshDx; // for diagnostics
228 
231  {};
232  TMquadRoot( TrimmedMapping& tm, const real& centerX_, const real& centerY_,
233  const real dx_ ) :
234  TMquad( tm, centerX_, centerY_, dx_ ),
236  {};
237  TMquadRoot& operator=( const TMquadRoot& tmq ) {
240  this->TMquad::operator=(tmq);
241  return *this;
242  };
243  int TMget( const GenericDataBase & dir, const aString & name,
244  TrimmedMapping& tm, TMcurves * curves_ = NULL );
245  virtual int put( GenericDataBase & dir, const aString & name) const;
246 
247 private:
248  TMquadRoot( const TMquad& tmq ) { cerr << "TMquad copy constructor call unexpected" << endl; };
249 
250 };
251 
252 #endif