DGtal  1.5.beta
NBijectiveReflectionGenerator.h
1 
17 #pragma once
18 
28 #if defined(NBIJECTIVEREFLECTIONGENERATOR_RECURSES)
29 #error Recursive header files inclusion detected in NBijectiveReflectionGenerator.h
30 #else // defined(CBDRFASTSOLVER_RECURSES)
32 #define NBIJECTIVEREFLECTIONGENERATOR_RECURSES
33 
34 #if !defined NBIJECTIVEREFLECTIONGENERATOR_h
36 #define NBIJECTIVEREFLECTIONGENERATOR_h
37 
39 // Inclusions
40 #include <iostream>
41 #include <fstream>
42 #include <algorithm>
43 #include <vector>
44 #include <sstream>
45 #include <fcntl.h>
46 #include <sys/mman.h>
47 #include <sys/stat.h>
48 #include <unistd.h>
49 #include <string>
50 #include "GAVector.h"
51 #include "DigitizedReflection.h"
52 #include "CBDR_naiverotation.h"
53 
54 namespace DGtal{
55  template<typename TSpace,typename TInputValue=typename TSpace::RealPoint>
57 
58  explicit NBijectiveGenerator(const size_t km):kmax(km){
59  for(int k=0; k<kmax; k++){
60  int x_kpp_k = (k+1);
61  int x_k_kpp = (k);
62  int x_1_2kpp = (1);
63  int x_2kpp_1 = (2*k+1);
64 
65 
66  int y_kpp_k = (k);
67  int y_k_kpp = (k+1);
68  int y_1_2kpp = (2*k+1);
69  int y_2kpp_1 = (1);
70 
71 
72  int x_kpp_k_m = (k+1);
73  int x_k_kpp_m = (k);
74  int x_1_2kpp_m = (1);
75  int x_2kpp_1_m = (2*k+1);
76 
77 
78  int y_kpp_k_m = -(k);
79  int y_k_kpp_m = -(k+1);
80  int y_1_2kpp_m = -(2*k+1);
81  int y_2kpp_1_m = -(1);
82 
83  BijectiveVectors.push_back(GAVector<TSpace>({x_kpp_k,y_kpp_k}));
84  BijectiveVectors.push_back(GAVector<TSpace>({x_k_kpp,y_k_kpp}));
85  BijectiveVectors.push_back(GAVector<TSpace>({x_1_2kpp,y_1_2kpp}));
86  BijectiveVectors.push_back(GAVector<TSpace>({x_2kpp_1,y_2kpp_1}));
87  BijectiveVectors.push_back(GAVector<TSpace>({x_kpp_k_m,y_kpp_k_m}));
88  BijectiveVectors.push_back(GAVector<TSpace>({x_k_kpp_m,y_k_kpp_m}));
89  BijectiveVectors.push_back(GAVector<TSpace>({x_1_2kpp_m,y_1_2kpp_m}));
90  BijectiveVectors.push_back(GAVector<TSpace>({x_2kpp_1_m,y_2kpp_1_m}));
91  }
92  }
93 
94 
95 
99  std::vector<std::pair<std::vector<int>,GAVector<TSpace>>> composeBijectiveReflections(
100  std::vector<std::pair<std::vector<int>,GAVector<TSpace>>>& Avector ){
101  std::vector<std::pair<std::vector<int>,GAVector<TSpace>>> result;
102  result.reserve(Avector.size()*BijectiveVectors.size());
103 
104  for(std::pair<std::vector<int>,GAVector<TSpace>> normalVectorsAndResult : Avector){
105  std::pair<std::vector<int>,GAVector<TSpace>> resultatCourant = normalVectorsAndResult;
106  for(size_t indexB = 0 ; indexB<BijectiveVectors.size();++indexB){
107  GAVector<TSpace> outVec = normalVectorsAndResult.second*BijectiveVectors[indexB];
108  if(outVec.my_gavec[0] <0){
109  // resultatCourant.first.insert(resultatCourant.first.begin(),indexB);
110  // resultatCourant.second = outVec*-1;
111  }else{
112  resultatCourant.first.push_back(indexB);
113  resultatCourant.second = outVec;
114  result.push_back(resultatCourant);
115  resultatCourant=normalVectorsAndResult;
116  }
117 
118  }
119  }
120  // unique
121  std::sort(result.begin(), result.end(), [](const std::pair<std::vector<int>,GAVector<TSpace>>& b1, const std::pair<std::vector<int>,GAVector<TSpace>>& b2) {
122  return b1.second < b2.second;});
123 
124 
125  return result;
126  }
127 
132  bool sameBijectiveComposition(const std::pair<std::vector<int>,GAVector<TSpace>>& b1, const std::pair<std::vector<int>,GAVector<TSpace>>& b2) const{
133  // both reflections thanks to reflection composer
134  if(fabs(b1.second.angleToXAxis()-b1.second.angleToXAxis())>1e-4){
135  return false;
136  }
137  std::vector<Reflection<TSpace,TInputValue>> normals1 = getGAVectorFromIndex(b1.first);
138  std::vector<Reflection<TSpace,TInputValue>> normals2 = getGAVectorFromIndex(b2.first);
139  CBDR_naiverotation<TSpace,TInputValue> reflectionsCompose1(normals1);
140  CBDR_naiverotation<TSpace,TInputValue> reflectionsCompose2(normals2);
141 
142  typename TSpace::Point zeroPt(0,0);
143 
144  for(int i =0 ; i<100;++i){
145  for(int j =0 ; j<100;++j){
146  double x=i-50;
147  double y=j-50;
148  typename TSpace::RealPoint pointCourant = {x,y};
149  typename TSpace::Point out1 = reflectionsCompose1(pointCourant);
150  typename TSpace::Point out2 = reflectionsCompose2(pointCourant);
151  if((out1-out2)!= zeroPt ){
152  return false;
153  }
154  }
155  }
156  return true;
157  }
158 
159 
160  std::vector<std::pair<std::vector<GAVector<TSpace>>,GAVector<TSpace>>> vecBijNormals_index_2_GAVector(const std::vector<std::pair<std::vector<int>,GAVector<TSpace>>>& vecBijNormalsIndex) {
161  std::vector<std::pair<std::vector<GAVector<TSpace>>,GAVector<TSpace>>> vecBijNormalsIndex_GAVector;
162  for(std::pair<std::vector<int>,GAVector<TSpace>> pairIndexGAVector : vecBijNormalsIndex) {
163  std::vector<GAVector<TSpace>> resGavec;
164 
165  for(int index : pairIndexGAVector.first) {
166  resGavec.push_back(BijectiveVectors[index]);
167  }
168  vecBijNormalsIndex_GAVector.push_back({resGavec,pairIndexGAVector.second});
169  }
170  return vecBijNormalsIndex_GAVector;
171 
172  }
173 
176  std::vector<std::pair<std::vector<int>,GAVector<TSpace>>> n_bijectiveReflections_get_NormalVectorsAngles(size_t n)
177  {
178  std::vector<std::pair<std::vector<int>,GAVector<TSpace>>> vecBijNormals;
179  for(int i =0 ; i< BijectiveVectors.size() ; ++i){
180  vecBijNormals.push_back({{i},BijectiveVectors[i]});
181  }
182  if(n>3) {
183  --n;
184  }
185 
186  for ( size_t j = 1; j < n; ++j )
187  {
188  vecBijNormals = composeBijectiveReflections( vecBijNormals);
189 
190  // remove duplicates with predicate defined below
191  auto last = std::unique(vecBijNormals.begin(),vecBijNormals.end(),[this](const std::pair<std::vector<int>,GAVector<TSpace>>& b1, const std::pair<std::vector<int>,GAVector<TSpace>>& b2) {
192  return sameBijectiveComposition(b1, b2);});
193  vecBijNormals.erase(last,vecBijNormals.end());
194  }
195  if(n==3){
197  for(auto& pairIndicesGAVec : vecBijNormals)
198  pairIndicesGAVec.first.insert(pairIndicesGAVec.first.begin(),0);
199  }
200 
201  std::sort(vecBijNormals.begin(), vecBijNormals.end(), [](const std::pair<std::vector<int>,GAVector<TSpace>>& b1, const std::pair<std::vector<int>,GAVector<TSpace>>& b2) {
202  return b1.second.angleToXAxis() < b2.second.angleToXAxis();});
203 
204 
205  return vecBijNormals;
206  }
207 
208  void displayNormalVectorsAndAngles(const std::vector<std::pair<std::vector<int>,GAVector<TSpace>>>& vecBijNormals){
209  for(size_t i =0;i<vecBijNormals.size();++i){
210  auto currentIndicesNormalVector=vecBijNormals[i].first;
211  GAVector<TSpace> finalNormalVec = vecBijNormals[i].second;
212 
213  if(2.0*finalNormalVec.angleToXAxis() < M_PI_4/8){
214  std::cout << "m=[";
215  for(int indexBijective : currentIndicesNormalVector){
216  std::cout <<"("<<BijectiveVectors[indexBijective].x<<","<<BijectiveVectors[indexBijective].y<<"),";
217  }
218  std::cout << "], angle="<<2.0*finalNormalVec.angleToXAxis()<<std::endl;
219  }
220  }
221  }
222 
224  std::vector<Reflection<TSpace>> getGAVectorFromIndex(const std::vector<int>& indices) const{
225  std::vector<Reflection<TSpace>> normals;
226  for(auto i : indices){
228  normals.push_back(refi);
229  }
230  return normals;
231  }
232 
233  void writeBijectiveVectors(const std::string& fileName, const std::vector<std::pair<std::vector<int>,GAVector<TSpace>>>& vecBijNormals){
234  std::ofstream file(fileName);
235 
236  file << "kmax="<<kmax<<std::endl;
237 
238  for(size_t i = 0;i<vecBijNormals.size();++i){
239  std::vector<int> gaNormalVecs = vecBijNormals[i].first;
240  for(auto index :gaNormalVecs)
241  file << "("<< BijectiveVectors[index].my_gavec[0] << ","<<BijectiveVectors[index].my_gavec[1]<<"),";
242  file << "("<<vecBijNormals[i].second.my_gavec[0]<<"," <<vecBijNormals[i].second.my_gavec[1]<<")"<<std::endl;
243  }
244  file.close();
245  }
246 
248  std::vector<std::pair<std::vector<GAVector<TSpace>>,GAVector<TSpace>>>& vecBijNormals,
249  typename std::vector<std::pair<std::vector<GAVector<TSpace>>,GAVector<TSpace>>>::iterator& lowerBound,
250  typename std::vector<std::pair<std::vector<GAVector<TSpace>>,GAVector<TSpace>>>::iterator& upperBound,
251  const int K,
252  const double targetAngle)
253  {
254  // find the index of the closest angle
255  int i = std::lower_bound(vecBijNormals.begin(), vecBijNormals.end(), targetAngle,[](const std::pair<std::vector<GAVector<TSpace>>,GAVector<TSpace>>& b1, const double b2) {
256  return 2.0*b1.second.angleToXAxis() < b2;
257  }) - vecBijNormals.begin();
258 
259  int leftCompo=i-1;
260  int rightCompo = i;
261 
262  // assume that K<vecBijNormals.size()
263  int numberElements=0;
264  while(numberElements<K){
265  if (leftCompo < 0 || (rightCompo < vecBijNormals.size() &&
266  fabs(2*vecBijNormals[leftCompo].second.angleToXAxis() - targetAngle) > fabs(2*vecBijNormals[rightCompo].second.angleToXAxis() - targetAngle))) {
267  rightCompo++;
268  }
269  else {
270  leftCompo--;
271  }
272  numberElements++;
273  }
274  lowerBound=vecBijNormals.begin()+leftCompo;
275  upperBound=vecBijNormals.begin()+rightCompo;
276 
277  }
278 
279  public:
280  size_t kmax;
281  std::vector<GAVector<TSpace>> BijectiveVectors;
282  };
283 
284 }
285 
286 
287 
288 #endif //NBIJECTIVEREFLECTIONGENERATOR
289 #undef NBIJECTIVEREFLECTIONGENERATOR_RECURSES
290 #endif // else defined(NBIJECTIVEREFLECTIONGENERATOR_RECURSES)
DGtal is the top-level namespace which contains all DGtal functions and types.
vec since the parameters are the vectors of digitized reflections
TInputValue my_gavec
Definition: GAVector.h:48
double angleToXAxis() const
Definition: GAVector.h:82
void displayNormalVectorsAndAngles(const std::vector< std::pair< std::vector< int >, GAVector< TSpace >>> &vecBijNormals)
void writeBijectiveVectors(const std::string &fileName, const std::vector< std::pair< std::vector< int >, GAVector< TSpace >>> &vecBijNormals)
std::vector< std::pair< std::vector< int >, GAVector< TSpace > > > n_bijectiveReflections_get_NormalVectorsAngles(size_t n)
generate all n =2,4 reflection composition
std::vector< GAVector< TSpace > > BijectiveVectors
bool sameBijectiveComposition(const std::pair< std::vector< int >, GAVector< TSpace >> &b1, const std::pair< std::vector< int >, GAVector< TSpace >> &b2) const
predicate to compare two composition of bijective reflections
std::vector< Reflection< TSpace > > getGAVectorFromIndex(const std::vector< int > &indices) const
getter function used in predicate
std::vector< std::pair< std::vector< int >, GAVector< TSpace > > > composeBijectiveReflections(std::vector< std::pair< std::vector< int >, GAVector< TSpace >>> &Avector)
compose bijective digitized reflections
std::vector< std::pair< std::vector< GAVector< TSpace > >, GAVector< TSpace > > > vecBijNormals_index_2_GAVector(const std::vector< std::pair< std::vector< int >, GAVector< TSpace >>> &vecBijNormalsIndex)
void getKNearestBijectiveComposition(std::vector< std::pair< std::vector< GAVector< TSpace >>, GAVector< TSpace >>> &vecBijNormals, typename std::vector< std::pair< std::vector< GAVector< TSpace >>, GAVector< TSpace >>>::iterator &lowerBound, typename std::vector< std::pair< std::vector< GAVector< TSpace >>, GAVector< TSpace >>>::iterator &upperBound, const int K, const double targetAngle)
unsigned int index(DGtal::uint32_t n, unsigned int b)
Definition: testBits.cpp:44
MyPointD Point
Definition: testClone2.cpp:383
KSpace K
PointVector< 3, double > RealPoint