DGtal  1.5.beta
InGeneralizedDiskOfGivenRadius.ih
1 /**
2  * This program is free software: you can redistribute it and/or modify
3  * it under the terms of the GNU Lesser General Public License as
4  * published by the Free Software Foundation, either version 3 of the
5  * License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program. If not, see <http://www.gnu.org/licenses/>.
14  *
15  **/
16 
17 /**
18  * @file InGeneralizedDiskOfGivenRadius.ih
19  * @author Tristan Roussillon (\c tristan.roussillon@liris.cnrs.fr )
20  * Laboratoire d'InfoRmatique en Image et Systèmes d'information - LIRIS (CNRS, UMR 5205), CNRS, France
21  *
22  * @date 2013/12/10
23  *
24  * Implementation of inline methods defined in InGeneralizedDiskOfGivenRadius.h
25  *
26  * This file is part of the DGtal library.
27  */
28 
29 
30 //////////////////////////////////////////////////////////////////////////////
31 #include <cstdlib>
32 //////////////////////////////////////////////////////////////////////////////
33 
34 ///////////////////////////////////////////////////////////////////////////////
35 // IMPLEMENTATION of inline methods.
36 ///////////////////////////////////////////////////////////////////////////////
37 
38 ///////////////////////////////////////////////////////////////////////////////
39 
40 
41 // ----------------------------------------------------------------------------
42 template <typename TPoint, typename TDetComputer>
43 inline
44 DGtal::InGeneralizedDiskOfGivenRadius<TPoint, TDetComputer>::
45 InGeneralizedDiskOfGivenRadius(bool isPositive,
46  const Integer& aNum2,
47  const Integer& aDen2)
48  : myNum2(aNum2), myDen2(aDen2),
49  myIsPositive( isPositive ),
50  myDetComputer(),
51  myP( Point() ),
52  myQ( Point() ),
53  myR( Point() ),
54  myComputedNum2( NumberTraits<Integer>::ZERO ),
55  myComputedDen2( NumberTraits<Integer>::ZERO ),
56  myPQ0( NumberTraits<Integer>::ZERO ),
57  myPQ1( NumberTraits<Integer>::ZERO ),
58  myPQnorm( NumberTraits<Integer>::ZERO ),
59  myQR0( NumberTraits<Integer>::ZERO ),
60  myQR1( NumberTraits<Integer>::ZERO ),
61  myQRnorm( NumberTraits<Integer>::ZERO ),
62  myRP0( NumberTraits<Integer>::ZERO ),
63  myRP1( NumberTraits<Integer>::ZERO ),
64  myRPnorm( NumberTraits<Integer>::ZERO ),
65  myArea( NumberTraits<Integer>::ZERO ),
66  myAreaFunctor()
67 {
68  if (myNum2 < NumberTraits<Integer>::ZERO)
69  myNum2 = -myNum2;
70 
71  if (myDen2 < NumberTraits<Integer>::ZERO)
72  myDen2 = -myDen2;
73 
74  myDetComputer.init( myDen2, myNum2 );
75 }
76 
77 // ----------------------------------------------------------------------------
78 template <typename TPoint, typename TDetComputer>
79 inline
80 void
81 DGtal::InGeneralizedDiskOfGivenRadius<TPoint, TDetComputer>::
82 init ( const Point& aP, const Point& aQ )
83 {
84  myP = aP;
85  myQ = aQ;
86 
87  myPQ0 = static_cast<Integer>(myQ[0]-myP[0]);
88  myPQ1 = static_cast<Integer>(myQ[1]-myP[1]);
89  myPQnorm = myPQ0*myPQ0 + myPQ1*myPQ1;
90  //myPQnorm must not be greater than the squared diameter, ie. 4 * myNum2 / myDen2
91  ASSERT( lengthIsValid( myPQnorm ) );
92 }
93 
94 // ----------------------------------------------------------------------------
95 template <typename TPoint, typename TDetComputer>
96 inline
97 void
98 DGtal::InGeneralizedDiskOfGivenRadius<TPoint, TDetComputer>::
99 init ( const PointArray& aA )
100 {
101  init( aA[0], aA[1] );
102 }
103 
104 // ----------------------------------------------------------------------------
105 template <typename TPoint, typename TDetComputer>
106 inline
107 typename DGtal::InGeneralizedDiskOfGivenRadius<TPoint, TDetComputer>::Value
108 DGtal::InGeneralizedDiskOfGivenRadius<TPoint, TDetComputer>::
109 operator() ( const Point& aR ) const
110 {
111  myR = aR;
112 
113  myQR0 = static_cast<Integer>(myR[0]-myQ[0]);
114  myQR1 = static_cast<Integer>(myR[1]-myQ[1]);
115 
116  myRP0 = static_cast<Integer>(myP[0]-myR[0]);
117  myRP1 = static_cast<Integer>(myP[1]-myR[1]);
118 
119  myArea = myAreaFunctor(myPQ0, myPQ1, myQR0, myQR1);
120 
121  if (myDen2 == NumberTraits<Integer>::ZERO)
122  { //comparison to an infinite radius
123  if (myIsPositive)
124  return myArea;
125  else
126  return -myArea;
127  }
128  else
129  { //comparison to a finite radius
130 
131  if (myIsPositive)
132  {
133  if (myArea > NumberTraits<Integer>::ZERO)
134  {
135  finalizeComputation();
136  return -myDetComputer( myComputedDen2, myComputedNum2 );
137  }
138  else
139  return -NumberTraits<Value>::ONE;
140  }
141  else
142  {
143  if (myArea < NumberTraits<Integer>::ZERO)
144  {
145  finalizeComputation();
146  return myDetComputer( myComputedDen2, myComputedNum2 );
147  }
148  else
149  return NumberTraits<Value>::ONE;
150  }
151  }
152 }
153 
154 
155 // ----------------------------------------------------------------------------
156 template <typename TPoint, typename TDetComputer>
157 inline
158 void
159 DGtal::InGeneralizedDiskOfGivenRadius<TPoint, TDetComputer>::
160 finalizeComputation () const
161 {
162  //squared denominator
163  myComputedDen2 = 4*myArea*myArea;
164 
165  //squared numerator
166  myQRnorm = myQR0*myQR0 + myQR1*myQR1;
167  //myQRnorm must not be greater than the squared diameter, ie. 4 * myNum2 / myDen2
168  ASSERT( lengthIsValid( myQRnorm ) );
169 
170  myRPnorm = myRP0*myRP0 + myRP1*myRP1;
171  //myRPnorm should be the greatest norm
172  ASSERT( (myRPnorm >= myPQnorm)&&(myRPnorm >= myQRnorm) );
173 
174  myComputedNum2 = myPQnorm*myQRnorm*myRPnorm;
175 }
176 
177 // ----------------------------------------------------------------------------
178 template <typename TPoint, typename TDetComputer>
179 inline
180 void
181 DGtal::InGeneralizedDiskOfGivenRadius<TPoint, TDetComputer>::
182 selfDisplay ( std::ostream & out ) const
183 {
184  out << "[InGeneralizedDiskOfGivenRadius]" << std::endl;
185  out << " radius: sqrt(" << myNum2 << "/" << myDen2 << ")";
186  if (myIsPositive)
187  out << "+";
188  else
189  out << "-";
190  out << std::endl;
191 }
192 
193 // ----------------------------------------------------------------------------
194 template <typename TPoint, typename TDetComputer>
195 inline
196 bool
197 DGtal::InGeneralizedDiskOfGivenRadius<TPoint, TDetComputer>::
198 lengthIsValid(const Integer& aL2) const
199 {
200  if (myDen2 == NumberTraits<Integer>::ZERO)
201  return true;
202  else
203  return ( myDetComputer( 4, aL2 ) <= 0 );
204 }
205 
206 // ----------------------------------------------------------------------------
207 template <typename TPoint, typename TDetComputer>
208 inline
209 bool
210 DGtal::InGeneralizedDiskOfGivenRadius<TPoint, TDetComputer>::
211 isValid() const
212 {
213  return ( (myNum2 > NumberTraits<Integer>::ZERO) &&
214  (myDen2 >= NumberTraits<Integer>::ZERO) );
215 }
216 
217 
218 
219 ///////////////////////////////////////////////////////////////////////////////
220 // Implementation of inline functions //
221 template <typename TPoint, typename TDetComputer>
222 inline
223 std::ostream&
224 DGtal::operator<< ( std::ostream & out,
225  const InGeneralizedDiskOfGivenRadius<TPoint, TDetComputer> & object )
226 {
227  object.selfDisplay( out );
228  return out;
229 }
230 
231 // //
232 ///////////////////////////////////////////////////////////////////////////////
233 
234