msbGrid  1.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
polygon.hh
Go to the documentation of this file.
1 /*****************************************************************************
2 * This program is part of the msbGrid software *
3 * *
4 * msbGrid stands for multi-structured block Grid generator *
5 * *
6 * msbGrid is a free software: you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation, either version 2 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * msbGrid is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * See the file COPYING for full copying permissions. *
17 *****************************************************************************/
23 #ifndef _POLYGON_HH_
24 #define _POLYGON_HH_
25 
26 #include <algorithm>
27 #include <cell.hh>
28 
29 namespace msbGrid
30 {
31 template< typename EntityT > /* EntityT can be Point or Edge */
33 {
34  EntityT *entPtr;
36 };
37 
38 /*
39  * Sort Container by angle
40  */
41 template< typename EntityT >
42 bool sortByAngle(const EntityAngle< EntityT > &entAngle1, const EntityAngle< EntityT > &entAngle2)
43 { return entAngle1.angle < entAngle2.angle; }
44 } /* namespace msbGrid */
45 
46 namespace msbGrid
47 {
48 template< int EdgeNumber >
49 class Polygon;
50 }
51 
52 template< int EdgeNumber >
53 class msbGrid :: Polygon : public msbGrid :: Cell
54 {
55 public:
58 
62 
63  enum { dim = 2 };
64 
65  static const int edgeNumber_ = EdgeNumber;
66  static const int verticesNumber_ = edgeNumber_;
67 
68 public:
69  Polygon(const std :: vector< Edge * > vEd0) : ParentT()
70  {
71  assert(dim == 2);
72  assert(vEd0.size() == edgeNumber_);
73 
74  this->pos().clear();
75  for ( unsigned int iDim = 0; iDim < dim; ++iDim ) {
76  Scalar som = 0.0;
77  for ( unsigned int iEd1 = 0; iEd1 < edgeNumber_; ++iEd1 ) {
78  som += vEd0 [ iEd1 ]->pos() [ iDim ];
79  }
80 
81  som /= edgeNumber_;
82 
83  this->pos().push_back(som);
84  }
85 
86  std :: vector< Edge * > vEd1( sortContainer_( vEd0 ) );
87  for ( unsigned int iEd1 = 0; iEd1 < edgeNumber_; ++iEd1 ) {
88  this->vEd().push_back(vEd1 [ iEd1 ]);
89  }
90 
91  std :: vector< Point * > vPt1;
92  for ( unsigned int iEd1 = 0; iEd1 < edgeNumber_; ++iEd1 ) {
93  for ( unsigned int iPt1 = 0; iPt1 < Edge :: verticesNumber_; ++iPt1 ) {
94  bool alreadyTaken = false;
95  for ( unsigned int iPt2 = 0; iPt2 < vPt1.size(); ++iPt2 ) {
96  if ( this->vEd() [ iEd1 ]->vPt() [ iPt1 ]->isIt(vPt1 [ iPt2 ]) ) {
97  alreadyTaken = true;
98  }
99  }
100 
101  if ( !alreadyTaken ) {
102  vPt1.push_back(this->vEd() [ iEd1 ]->vPt() [ iPt1 ]);
103  }
104  }
105  }
106 
107  std :: vector< Point * > vPt2( sortContainer_( vPt1 ) );
108  if ( !superposed(Edge(vPt2 [ 0 ], vPt2 [ 1 ]), * this->vEd() [ 0 ]) ) {
109  vPt2.insert( vPt2.begin(), vPt2.back() );
110  }
111 
112  for ( unsigned int iPt1 = 0; iPt1 < edgeNumber_; ++iPt1 ) {
113  this->vPt().push_back(vPt2 [ iPt1 ]);
114  }
115  }
116  ~Polygon() {}
117 
118  friend const bool superposed(const ThisT &pl0, const ThisT &pl1)
119  {
120  int superposedEdgeNumber = 0;
121  for ( unsigned int ie0 = 0; ie0 < pl0.vEd().size(); ++ie0 ) {
122  for ( unsigned int ie1 = 0; ie1 < pl1.vEd().size(); ++ie1 ) {
123  if ( superposed(* pl0.vEd() [ ie0 ], * pl1.vEd() [ ie1 ]) ) {
124  ++superposedEdgeNumber;
125  }
126  }
127  }
128 
129  return ( superposedEdgeNumber == edgeNumber_ );
130  }
131 
132  void translate(const std :: vector< Scalar > &dx)
133  {
134  for ( unsigned int iPt = 0; iPt < verticesNumber_; ++iPt ) {
135  this->vPt() [ iPt ].translate(dx);
136  }
137  }
138 
139 private:
140  template< typename EntityT >
141  const std :: vector< EntityT * > sortContainer_(const std :: vector< EntityT * > &vEnt0) const
142  {
143  /*
144  * the following sort strategy is inspired from : http://www.cplusplus.com/articles/NhA0RXSz/
145  * Warning: Uses C++11 Features
146  */
147  Point a(this->pos() [ 0 ] + Scalar(0.1), this->pos() [ 1 ]);
148  Point b(this->pos() [ 0 ], this->pos() [ 1 ]);
149 
150  std :: vector< EntityAngle< EntityT > > vEntAngle;
151  vEntAngle.resize(edgeNumber_);
152  for ( unsigned int iEnt1 = 0; iEnt1 < edgeNumber_; ++iEnt1 ) {
153  Point c(vEnt0 [ iEnt1 ]->pos() [ 0 ], vEnt0 [ iEnt1 ]->pos() [ 1 ]);
154  vEntAngle [ iEnt1 ].entPtr = vEnt0 [ iEnt1 ];
155  vEntAngle [ iEnt1 ].angle = angle(a, b, c);
156  }
157 
158  sort(vEntAngle.begin(), vEntAngle.end(), sortByAngle< EntityT > );
159 
160  std :: vector< EntityT * > vEnt1;
161  vEnt1.clear();
162 
163  for ( unsigned int iEnt1 = 0; iEnt1 < edgeNumber_; ++iEnt1 ) {
164 #if CLOCKWISE_ROTATION_SENSE == 0
165  vEnt1.push_back(vEntAngle [ iEnt1 ].entPtr);
166 #endif
167 #if CLOCKWISE_ROTATION_SENSE == 1
168  vEnt1.push_back(vEntAngle [ ( edgeNumber_ - iEnt1 - 1 ) ].entPtr);
169 #endif
170  }
171 
172  return vEnt1;
173  }
174 };
175 
176 #endif /* #ifndef _POLYGON_HH_ */