DGtal  1.2.0
ArithmeticalDSLKernel.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 ArithmeticalDSLKernel.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/07/02
23  *
24  * Implementation of inline methods defined in ArithmeticalDSLKernel.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 template <typename TCoordinate, unsigned short adjacency>
41 template <typename TInteger>
42 inline
43 typename DGtal::ArithmeticalDSLKernel<TCoordinate,adjacency>::Vector
44 DGtal::ArithmeticalDSLKernel<TCoordinate,adjacency>
45 ::shift(const TInteger& a, const TInteger& b)
46 {
47  Vector res;
48  if (b == NumberTraits<TInteger>::ZERO)
49  {
50  if (a == NumberTraits<TInteger>::ZERO) //no octant
51  res = Vector(NumberTraits<TCoordinate>::ZERO,NumberTraits<TCoordinate>::ZERO);
52  else if (a > NumberTraits<TInteger>::ZERO) //octant 2
53  res = Vector(NumberTraits<TCoordinate>::ONE,NumberTraits<TCoordinate>::ZERO);
54  else // (a < 0) //octant 6
55  res = Vector(-NumberTraits<TCoordinate>::ONE,NumberTraits<TCoordinate>::ZERO);
56  }
57  else if (b > NumberTraits<TInteger>::ZERO)
58  {
59  if (a == NumberTraits<TInteger>::ZERO) //octant 0
60  res = Vector(NumberTraits<TCoordinate>::ZERO,-NumberTraits<TCoordinate>::ONE);
61  else if (a > NumberTraits<TInteger>::ZERO)
62  {
63  if (b > a) //octant 0
64  res = Vector(NumberTraits<TCoordinate>::ZERO,-NumberTraits<TCoordinate>::ONE);
65  else //octant 1
66  res = Vector(NumberTraits<TCoordinate>::ONE,NumberTraits<TCoordinate>::ZERO);
67  }
68  else // (a < 0)
69  {
70  if (b >= -a) //octant 7
71  res = Vector(NumberTraits<TCoordinate>::ZERO,-NumberTraits<TCoordinate>::ONE);
72  else //octant 6
73  res = Vector(-NumberTraits<TCoordinate>::ONE,NumberTraits<TCoordinate>::ZERO);
74  }
75  }
76  else // (b < 0)
77  {
78  if (a == NumberTraits<TInteger>::ZERO) //octant 4
79  res = Vector(NumberTraits<TCoordinate>::ZERO,NumberTraits<TCoordinate>::ONE);
80  else if (a > NumberTraits<TInteger>::ZERO)
81  {
82  if (-b >= a) //octant 3
83  res = Vector(NumberTraits<TCoordinate>::ZERO,NumberTraits<TCoordinate>::ONE);
84  else //octant 2
85  res = Vector(NumberTraits<TCoordinate>::ONE,NumberTraits<TCoordinate>::ZERO);
86  }
87  else // (a < 0)
88  {
89  if (-b > -a) //octant 4
90  res = Vector(NumberTraits<TCoordinate>::ZERO,NumberTraits<TCoordinate>::ONE);
91  else //octant 5
92  res = Vector(-NumberTraits<TCoordinate>::ONE,NumberTraits<TCoordinate>::ZERO);
93  }
94  }
95  return res;
96 }
97 
98 // ----------------------------------------------------------------------------
99 template <typename TCoordinate, unsigned short adjacency>
100 template <typename TInteger>
101 inline
102 typename DGtal::ArithmeticalDSLKernel<TCoordinate,adjacency>::Steps
103 DGtal::ArithmeticalDSLKernel<TCoordinate,adjacency>
104 ::steps(const TInteger& a, const TInteger& b)
105 {
106  Steps steps;
107  if (b == NumberTraits<TInteger>::ZERO)
108  {
109  if (a == NumberTraits<TInteger>::ZERO)
110  { //no octant
111  steps.first = Vector(NumberTraits<TCoordinate>::ZERO,NumberTraits<TCoordinate>::ZERO);
112  steps.second = Vector(NumberTraits<TCoordinate>::ZERO,NumberTraits<TCoordinate>::ZERO);
113  }
114  else if (a > NumberTraits<TInteger>::ZERO)
115  { //octant 2
116  steps.first = Vector(NumberTraits<TCoordinate>::ZERO,NumberTraits<TCoordinate>::ONE);
117  steps.second = Vector(NumberTraits<TCoordinate>::ZERO,NumberTraits<TCoordinate>::ZERO);
118  }
119  else // (a < 0)
120  { //octant 6
121  steps.first = Vector(NumberTraits<TCoordinate>::ZERO,-NumberTraits<TCoordinate>::ONE);
122  steps.second = Vector(NumberTraits<TCoordinate>::ZERO,NumberTraits<TCoordinate>::ZERO);
123  }
124  }
125  else if (b > NumberTraits<TInteger>::ZERO)
126  {
127  if (a == NumberTraits<TInteger>::ZERO)
128  { //octant 0
129  steps.first = Vector(NumberTraits<TCoordinate>::ONE,NumberTraits<TCoordinate>::ZERO);
130  steps.second = Vector(NumberTraits<TCoordinate>::ZERO,NumberTraits<TCoordinate>::ZERO);
131  }
132  else if (a > NumberTraits<TInteger>::ZERO)
133  {
134  if (b == a)
135  {
136  steps.first = Vector(NumberTraits<TCoordinate>::ONE,NumberTraits<TCoordinate>::ONE);
137  steps.second = Vector(NumberTraits<TCoordinate>::ZERO,NumberTraits<TCoordinate>::ZERO);
138  }
139  else if (b > a)
140  { //octant 0
141  steps.first = Vector(NumberTraits<TCoordinate>::ONE,NumberTraits<TCoordinate>::ZERO);
142  steps.second = Vector(NumberTraits<TCoordinate>::ONE,NumberTraits<TCoordinate>::ONE);
143  }
144  else // (b < a)
145  { //octant 1
146  steps.second = Vector(NumberTraits<TCoordinate>::ZERO,NumberTraits<TCoordinate>::ONE);
147  steps.first = Vector(NumberTraits<TCoordinate>::ONE,NumberTraits<TCoordinate>::ONE);
148  }
149  }
150  else //(a < 0)
151  {
152  if (b == -a)
153  {
154  steps.first = Vector(NumberTraits<TCoordinate>::ONE,-NumberTraits<TCoordinate>::ONE);
155  steps.second = Vector(NumberTraits<TCoordinate>::ZERO,NumberTraits<TCoordinate>::ZERO);
156  }
157  else if (b > -a)
158  { //octant 7
159  steps.second = Vector(NumberTraits<TCoordinate>::ONE,NumberTraits<TCoordinate>::ZERO);
160  steps.first = Vector(NumberTraits<TCoordinate>::ONE,-NumberTraits<TCoordinate>::ONE);
161  }
162  else // (b < -a)
163  { //octant 6
164  steps.first = Vector(NumberTraits<TCoordinate>::ZERO,-NumberTraits<TCoordinate>::ONE);
165  steps.second = Vector(NumberTraits<TCoordinate>::ONE,-NumberTraits<TCoordinate>::ONE);
166  }
167  }
168  }
169  else // (b < 0)
170  {
171  if (a == NumberTraits<TInteger>::ZERO)
172  { //octant 4
173  steps.first = Vector(-NumberTraits<TCoordinate>::ONE,NumberTraits<TCoordinate>::ZERO);
174  steps.second = Vector(NumberTraits<TCoordinate>::ZERO,NumberTraits<TCoordinate>::ZERO);
175  }
176  else if (a > NumberTraits<TInteger>::ZERO)
177  {
178  if (-b == a)
179  {
180  steps.first = Vector(-NumberTraits<TCoordinate>::ONE,NumberTraits<TCoordinate>::ONE);
181  steps.second = Vector(NumberTraits<TCoordinate>::ZERO,NumberTraits<TCoordinate>::ZERO);
182  }
183  else if (-b > a)
184  { //octant 3
185  steps.second = Vector(-NumberTraits<TCoordinate>::ONE,NumberTraits<TCoordinate>::ZERO);
186  steps.first = Vector(-NumberTraits<TCoordinate>::ONE,NumberTraits<TCoordinate>::ONE);
187  }
188  else // (-b < a)
189  { //octant 2
190  steps.first = Vector(NumberTraits<TCoordinate>::ZERO,NumberTraits<TCoordinate>::ONE);
191  steps.second = Vector(-NumberTraits<TCoordinate>::ONE,NumberTraits<TCoordinate>::ONE);
192  }
193  }
194  else // (a < 0)
195  {
196  if (-b == -a)
197  {
198  steps.first = Vector(-NumberTraits<TCoordinate>::ONE,-NumberTraits<TCoordinate>::ONE);
199  steps.second = Vector(NumberTraits<TCoordinate>::ZERO,NumberTraits<TCoordinate>::ZERO);
200  }
201  else if (-b > -a)
202  { //octant 4
203  steps.first = Vector(-NumberTraits<TCoordinate>::ONE,NumberTraits<TCoordinate>::ZERO);
204  steps.second = Vector(-NumberTraits<TCoordinate>::ONE,-NumberTraits<TCoordinate>::ONE);
205  }
206  else // (-b < -a)
207  { //octant 5
208  steps.second = Vector(NumberTraits<TCoordinate>::ZERO,-NumberTraits<TCoordinate>::ONE);
209  steps.first = Vector(-NumberTraits<TCoordinate>::ONE,-NumberTraits<TCoordinate>::ONE);
210  }
211  }
212  }
213  return steps;
214 }
215 
216 // ----------------------------------------------------------------------------
217 template <typename TCoordinate, unsigned short adjacency>
218 template <typename TInteger>
219 inline
220 TInteger
221 DGtal::ArithmeticalDSLKernel<TCoordinate,adjacency>
222 ::norm(const TInteger& a, const TInteger& b)
223 {
224  if (b >= NumberTraits<TInteger>::ZERO)
225  {
226  if (a >= NumberTraits<TInteger>::ZERO)
227  {
228  if (b >= a)
229  return b;
230  else
231  return a;
232  }
233  else
234  {
235  if (b >= -a)
236  return b;
237  else
238  return -a;
239  }
240  }
241  else
242  {
243  if (a >= NumberTraits<TInteger>::ZERO)
244  {
245  if (-b >= a)
246  return -b;
247  else
248  return a;
249  }
250  else
251  {
252  if (-b >= -a)
253  return -b;
254  else
255  return -a;
256  }
257  }
258 }
259 
260 // ----------------------------------------------------------------------------
261 template <typename TCoordinate>
262 template <typename TInteger>
263 inline
264 typename DGtal::ArithmeticalDSLKernel<TCoordinate,4>::Vector
265 DGtal::ArithmeticalDSLKernel<TCoordinate,4>
266 ::shift(const TInteger& a, const TInteger& b)
267 {
268  Vector res;
269  if (b == NumberTraits<TInteger>::ZERO)
270  {
271  if (a == NumberTraits<TInteger>::ZERO)
272  { //no quadrant
273  res = Vector(NumberTraits<TCoordinate>::ZERO,NumberTraits<TCoordinate>::ZERO);
274  }
275  else if (a > NumberTraits<TInteger>::ZERO)
276  { //quadrant 1
277  res = Vector(NumberTraits<TCoordinate>::ONE,NumberTraits<TCoordinate>::ONE);
278  }
279  else // (a < 0)
280  { //quadrant 3
281  res = Vector(-NumberTraits<TCoordinate>::ONE,-NumberTraits<TCoordinate>::ONE);
282  }
283  }
284  else if (b > NumberTraits<TInteger>::ZERO)
285  {
286  if (a >= NumberTraits<TInteger>::ZERO)
287  { //quadrant 0
288  res = Vector(NumberTraits<TCoordinate>::ONE,-NumberTraits<TCoordinate>::ONE);
289  }
290  else // (a < 0)
291  { //quadrant 3
292  res = Vector(-NumberTraits<TCoordinate>::ONE,-NumberTraits<TCoordinate>::ONE);
293  }
294  }
295  else // (b < 0)
296  {
297  if (a > NumberTraits<TInteger>::ZERO)
298  { //quadrant 1
299  res = Vector(NumberTraits<TCoordinate>::ONE,NumberTraits<TCoordinate>::ONE);
300  }
301  else // (a <= 0)
302  { //quadrant 2
303  res = Vector(-NumberTraits<TCoordinate>::ONE,NumberTraits<TCoordinate>::ONE);
304  }
305  }
306  return res;
307 }
308 
309 // ----------------------------------------------------------------------------
310 template <typename TCoordinate>
311 template <typename TInteger>
312 inline
313 typename DGtal::ArithmeticalDSLKernel<TCoordinate,4>::Steps
314 DGtal::ArithmeticalDSLKernel<TCoordinate,4>
315 ::steps(const TInteger& a, const TInteger& b)
316 {
317  Steps steps;
318  if (b == NumberTraits<TInteger>::ZERO)
319  {
320  if (a == NumberTraits<TInteger>::ZERO)
321  { //no quadrant
322  steps.first = Vector(NumberTraits<TCoordinate>::ZERO,NumberTraits<TCoordinate>::ZERO);
323  steps.second = Vector(NumberTraits<TCoordinate>::ZERO,NumberTraits<TCoordinate>::ZERO);
324  }
325  else if (a > NumberTraits<TInteger>::ZERO)
326  {
327  steps.first = Vector(NumberTraits<TCoordinate>::ZERO,NumberTraits<TCoordinate>::ONE);
328  steps.second = Vector(NumberTraits<TCoordinate>::ZERO,NumberTraits<TCoordinate>::ZERO);
329  }
330  else // (a < 0)
331  {
332  steps.first = Vector(NumberTraits<TCoordinate>::ZERO,-NumberTraits<TCoordinate>::ONE);
333  steps.second = Vector(NumberTraits<TCoordinate>::ZERO,NumberTraits<TCoordinate>::ZERO);
334  }
335  }
336  else if (b > NumberTraits<TInteger>::ZERO)
337  {
338  if (a == NumberTraits<TInteger>::ZERO)
339  {
340  steps.first = Vector(NumberTraits<TCoordinate>::ONE,NumberTraits<TCoordinate>::ZERO);
341  steps.second = Vector(NumberTraits<TCoordinate>::ZERO,NumberTraits<TCoordinate>::ZERO);
342  }
343  else if (a > NumberTraits<TInteger>::ZERO)
344  { //quadrant 0
345  steps.first = Vector(NumberTraits<TCoordinate>::ONE,NumberTraits<TCoordinate>::ZERO);
346  steps.second = Vector(NumberTraits<TCoordinate>::ZERO,NumberTraits<TCoordinate>::ONE);
347  }
348  else // (a < 0)
349  { //quadrant 3
350  steps.second = Vector(NumberTraits<TCoordinate>::ONE,NumberTraits<TCoordinate>::ZERO);
351  steps.first = Vector(NumberTraits<TCoordinate>::ZERO,-NumberTraits<TCoordinate>::ONE);
352  }
353  }
354  else // (b < 0)
355  {
356  if (a == NumberTraits<TInteger>::ZERO)
357  {
358  steps.first = Vector(-NumberTraits<TCoordinate>::ONE,NumberTraits<TCoordinate>::ZERO);
359  steps.second = Vector(NumberTraits<TCoordinate>::ZERO,NumberTraits<TCoordinate>::ZERO);
360  }
361  else if (a > NumberTraits<TInteger>::ZERO)
362  { //quadrant 1
363  steps.second = Vector(-NumberTraits<TCoordinate>::ONE,NumberTraits<TCoordinate>::ZERO);
364  steps.first = Vector(NumberTraits<TCoordinate>::ZERO,NumberTraits<TCoordinate>::ONE);
365  }
366  else // (a < 0)
367  { //quadrant 2
368  steps.first = Vector(-NumberTraits<TCoordinate>::ONE,NumberTraits<TCoordinate>::ZERO);
369  steps.second = Vector(NumberTraits<TCoordinate>::ZERO,-NumberTraits<TCoordinate>::ONE);
370  }
371  }
372  return steps;
373 }
374 
375 // ----------------------------------------------------------------------------
376 template <typename TCoordinate>
377 template <typename TInteger>
378 inline
379 TInteger
380 DGtal::ArithmeticalDSLKernel<TCoordinate,4>
381 ::norm(const TInteger& a, const TInteger& b)
382 {
383  if (b >= NumberTraits<TInteger>::ZERO)
384  {
385  if (a >= NumberTraits<TInteger>::ZERO)
386  return b+a;
387  else
388  return b-a;
389  }
390  else
391  {
392  if (a >= NumberTraits<TInteger>::ZERO)
393  return -b+a;
394  else
395  return -b-a;
396  }
397 }
398 
399