ViSP  2.9.0
vpMomentAlpha.cpp
1 /****************************************************************************
2  *
3  * $Id: vpMomentAlpha.cpp 4649 2014-02-07 14:57:11Z fspindle $
4  *
5  * This file is part of the ViSP software.
6  * Copyright (C) 2005 - 2014 by INRIA. All rights reserved.
7  *
8  * This software is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * ("GPL") version 2 as published by the Free Software Foundation.
11  * See the file LICENSE.txt at the root directory of this source
12  * distribution for additional information about the GNU GPL.
13  *
14  * For using ViSP with software that can not be combined with the GNU
15  * GPL, please contact INRIA about acquiring a ViSP Professional
16  * Edition License.
17  *
18  * See http://www.irisa.fr/lagadic/visp/visp.html for more information.
19  *
20  * This software was developed at:
21  * INRIA Rennes - Bretagne Atlantique
22  * Campus Universitaire de Beaulieu
23  * 35042 Rennes Cedex
24  * France
25  * http://www.irisa.fr/lagadic
26  *
27  * If you have questions regarding the use of this file, please contact
28  * INRIA at visp@inria.fr
29  *
30  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
31  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
32  *
33  *
34  * Description:
35  * Alpha moment descriptor for in-plane orientation.
36  *
37  * Authors:
38  * Filip Novotny
39  *
40  *****************************************************************************/
41 
42 #include <visp/vpMomentAlpha.h>
43 #include <visp/vpMomentGravityCenter.h>
44 #include <visp/vpMomentCentered.h>
45 #include <cmath>
46 
52 vpMomentAlpha::vpMomentAlpha() : isRef(true), symmetric(false), ref(), alphaRef(0.) {
53  values.resize(1);
54 }
55 
63 vpMomentAlpha::vpMomentAlpha(std::vector<double>& ref_, double alpha_ref)
64  : vpMoment(),isRef(false),symmetric(false),ref(ref_),alphaRef(alpha_ref)
65 {
66  for (std::vector<double>::iterator it = ref_.begin(); it!=ref_.end(); it++)
67  if (*it<=1e-4)
68  symmetric = true;
69 
70  values.resize(1);
71 }
72 
78  //symmetric = symmetric | this->getObject().isSymmetric();
79  bool found_moment_centered;
80 
81  const vpMomentCentered& momentCentered = (static_cast<const vpMomentCentered&> (getMoments().get("vpMomentCentered",
82  found_moment_centered)));
83 
84  if (!found_moment_centered)
85  throw vpException(vpException::notInitialized, "vpMomentCentered not found");
86 
87  double alpha = 0.5 * atan2(2.0 * momentCentered.get(1, 1), (momentCentered.get(2, 0) - momentCentered.get(0, 2)));
88 
89  unsigned int order = 4;
90  std::vector<double> rotMu(4);
91  std::vector<double> realMu(4);
92 
93  if (isRef)
94  {
95  alphaRef = alpha;
96  }
97  else
98  {
99  if (!symmetric)
100  {
101  double r11 = cos(alpha - alphaRef);
102  double r12 = sin(alpha - alphaRef);
103  double r21 = -sin(alpha - alphaRef);
104  double r22 = cos(alpha - alphaRef);
105  unsigned int idx = 0;
106  for (register unsigned int c = 0; c < (order) * (order); c++)
107  {
108  unsigned int i = c % order;
109  unsigned int j = c / order;
110 
111  if (i + j == 3)
112  {
113  double r11_k = 1.;
114  for (register unsigned int k = 0; k <= i; k++)
115  {
116  double r12_i_k = pow(r12, (int)(i - k));
117  double comb_i_k = static_cast<double> (vpMath::comb(i, k));
118  for (register unsigned int l = 0; l <= j; l++)
119  {
120  rotMu[idx] += static_cast<double> (comb_i_k * vpMath::comb(j, l) * r11_k * pow(r21, (int)l) * r12_i_k
121  * pow(r22, (int)(j - l)) * momentCentered.get(k + l, (unsigned int)(int)(i + j - k - l)));
122  }
123  r11_k *= r11;
124  }
125  realMu[idx] = momentCentered.get(i, j);
126  idx++;
127  }
128  }
129 
130  double sum = 0.;
131  bool signChange = true;
132  for (register unsigned int i = 0; i < 4; i++)
133  {
134  if (std::abs(rotMu[i]) > 1e10 * std::numeric_limits<double>::epsilon() && std::abs(ref[i]) > 1e10
135  * std::numeric_limits<double>::epsilon() && rotMu[i] * ref[i] > 0)
136  signChange = false;
137  sum += std::abs(rotMu[i] * ref[i]);
138  }
139 
140  if (sum < 1e4 * std::numeric_limits<double>::epsilon())
141  signChange = false;
142  if (signChange)
143  alpha = alpha + M_PI;
144  }
145  }
146  values[0] = alpha;
147 }
148 
152 VISP_EXPORT std::ostream & operator<<(std::ostream & os, const vpMomentAlpha& c){
153  os << c.values[0] ;
154  return os;
155 }
vpMomentDatabase & getMoments()
Definition: vpMoment.h:119
error that can be emited by ViSP classes.
Definition: vpException.h:76
This class defines shared methods/attributes for 2D moments.
Definition: vpMoment.h:108
const vpMoment & get(const char *type, bool &found) const
This class defines the double-indexed centered moment descriptor .
This class defines the orientation of the object inside the plane parallel to the object...
double get(unsigned int i, unsigned int j) const
static long double comb(unsigned int n, unsigned int p)
Definition: vpMath.h:213
std::vector< double > values
Definition: vpMoment.h:114