Visual Servoing Platform  version 3.6.1 under development (2024-05-16)
testImageCircle.cpp
1 /*
2  * ViSP, open source Visual Servoing Platform software.
3  * Copyright (C) 2005 - 2023 by Inria. All rights reserved.
4  *
5  * This software is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  * See the file LICENSE.txt at the root directory of this source
10  * distribution for additional information about the GNU GPL.
11  *
12  * For using ViSP with software that can not be combined with the GNU
13  * GPL, please contact Inria about acquiring a ViSP Professional
14  * Edition License.
15  *
16  * See https://visp.inria.fr for more information.
17  *
18  * This software was developed at:
19  * Inria Rennes - Bretagne Atlantique
20  * Campus Universitaire de Beaulieu
21  * 35042 Rennes Cedex
22  * France
23  *
24  * If you have questions regarding the use of this file, please contact
25  * Inria at visp@inria.fr
26  *
27  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
28  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
29  *
30  * Description:
31  * Test vpRect and vpImagePoint.
32  */
33 
34 #include <iostream>
35 #include <visp3/core/vpConfig.h>
36 #include <visp3/core/vpImageCircle.h>
37 #include <visp3/core/vpMath.h>
38 #include <visp3/core/vpRect.h>
39 
40 bool equal(const float &actualVal, const float &theoreticalVal)
41 {
42  // Allow up to 1 pixel of difference, due to rounding effects
43  return (std::abs(theoreticalVal - actualVal) < 1.f);
44 }
45 
46 int main()
47 {
48  const float OFFSET = 5.f;
49  const float WIDTH = 640.f;
50  const float HEIGHT = 480.f;
51  const float RADIUS = std::min<float>(WIDTH, HEIGHT) / 10.f;
52  vpRect roi(OFFSET, OFFSET, WIDTH, HEIGHT);
53  const float WIDTH_SWITCHED = HEIGHT; // The RoI must be inverted in order to cross left and right axes while crossing only the top axis
54  const float HEIGHT_SWITCHED = WIDTH; // The RoI must be inverted in order to cross left and right axes while crossing only the top axis
55  vpRect switchedRoI(OFFSET, OFFSET, WIDTH_SWITCHED, HEIGHT_SWITCHED);
56  bool hasSucceeded = true;
57 
58  // Test with no intersections
59  {
60  vpImageCircle circle(vpImagePoint(HEIGHT / 2.f, WIDTH / 2.f), RADIUS);
61  float arcLengthCircle = circle.computeArcLengthInRoI(roi);
62  float theoreticalValue = 2.f * M_PIf * RADIUS;
63  bool isValueOK = equal(arcLengthCircle, theoreticalValue);
64  std::string statusTest;
65  if (isValueOK) {
66  statusTest = "SUCCESS";
67  }
68  else {
69  statusTest = "FAILED";
70  }
71  std::cout << "Test no intersection." << std::endl;
72  std::cout << "\tarc length =" << arcLengthCircle << std::endl;
73  std::cout << "\ttheoretical length =" << theoreticalValue << std::endl;
74  std::cout << "\ttest status = " << statusTest << std::endl;
75 
76  hasSucceeded &= isValueOK;
77  }
78 
79  // Test circle touching borders of the RoI
80  {
81  vpRect roiSquare(OFFSET, OFFSET, HEIGHT, HEIGHT);
82  vpImageCircle circle(vpImagePoint(OFFSET + HEIGHT / 2.f, OFFSET + HEIGHT / 2.f), HEIGHT / 2.f);
83  float arcLengthCircle = circle.computeArcLengthInRoI(roi);
84  float theoreticalValue = 2.f * M_PIf * HEIGHT / 2.f;
85  bool isValueOK = equal(arcLengthCircle, theoreticalValue);
86  std::string statusTest;
87  if (isValueOK) {
88  statusTest = "SUCCESS";
89  }
90  else {
91  statusTest = "FAILED";
92  }
93  std::cout << "Test circle touching borders of the RoI." << std::endl;
94  std::cout << "\tarc length =" << arcLengthCircle << std::endl;
95  std::cout << "\ttheoretical length =" << theoreticalValue << std::endl;
96  std::cout << "\ttest status = " << statusTest << std::endl;
97 
98  hasSucceeded &= isValueOK;
99  }
100 
101  // Test with intersections with the left border, more than half a circle visible
102  {
103  // Formula: uc = OFFSET - RADIUS * cos(theta)
104  // theta := 2 * PI / 3
105  float uc = OFFSET + 24.f;
106  float vc = OFFSET + 100.f;
107  vpImageCircle circle(vpImagePoint(vc, uc), RADIUS);
108  float arcLengthCircle = circle.computeArcLengthInRoI(roi);
109  float theoreticalValue = 4.f * M_PIf * RADIUS /3.f;
110  bool isValueOK = equal(arcLengthCircle, theoreticalValue);
111  std::string statusTest;
112  if (isValueOK) {
113  statusTest = "SUCCESS";
114  }
115  else {
116  statusTest = "FAILED";
117  }
118  std::cout << "Test intersection left border, more than half a circle visible." << std::endl;
119  std::cout << "\tarc length =" << arcLengthCircle << std::endl;
120  std::cout << "\ttheoretical length =" << theoreticalValue << std::endl;
121  std::cout << "\ttest status = " << statusTest << std::endl;
122 
123  hasSucceeded &= isValueOK;
124  }
125 
126  // Test with intersections with the left border, less than half a circle visible
127  {
128  // Formula: uc = OFFSET - RADIUS * cos(theta)
129  // theta := PI / 3
130  float uc = OFFSET - 24.f;
131  float vc = OFFSET + 100.f;
132  vpImageCircle circle(vpImagePoint(vc, uc), RADIUS);
133  float arcLengthCircle = circle.computeArcLengthInRoI(roi);
134  float theoreticalValue = 2.f * M_PIf * RADIUS /3.f;
135  bool isValueOK = equal(arcLengthCircle, theoreticalValue);
136  std::string statusTest;
137  if (isValueOK) {
138  statusTest = "SUCCESS";
139  }
140  else {
141  statusTest = "FAILED";
142  }
143  std::cout << "Test intersection left border, less than half a circle visible." << std::endl;
144  std::cout << "\tarc length =" << arcLengthCircle << std::endl;
145  std::cout << "\ttheoretical length =" << theoreticalValue << std::endl;
146  std::cout << "\ttest status = " << statusTest << std::endl;
147 
148  hasSucceeded &= isValueOK;
149  }
150 
151  // Test with circle touching the left border, all the circle is visible
152  {
153  // Formula: uc = OFFSET - RADIUS * cos(theta)
154  // theta := PI
155  float uc = OFFSET + RADIUS;
156  float vc = OFFSET + 100.f;
157  vpImageCircle circle(vpImagePoint(vc, uc), RADIUS);
158  float arcLengthCircle = circle.computeArcLengthInRoI(roi);
159  float theoreticalValue = 2.f * M_PIf * RADIUS;
160  bool isValueOK = equal(arcLengthCircle, theoreticalValue);
161  std::string statusTest;
162  if (isValueOK) {
163  statusTest = "SUCCESS";
164  }
165  else {
166  statusTest = "FAILED";
167  }
168  std::cout << "Test with circle touching the left border, all the circle is visible." << std::endl;
169  std::cout << "\tarc length =" << arcLengthCircle << std::endl;
170  std::cout << "\ttheoretical length =" << theoreticalValue << std::endl;
171  std::cout << "\ttest status = " << statusTest << std::endl;
172 
173  hasSucceeded &= isValueOK;
174  }
175 
176  // Test with circle touching the left border, all the circle is hidden
177  {
178  // Formula: uc = OFFSET - RADIUS * cos(theta)
179  // theta := PI
180  float uc = OFFSET - RADIUS;
181  float vc = OFFSET - 100.f;
182  vpImageCircle circle(vpImagePoint(vc, uc), RADIUS);
183  float arcLengthCircle = circle.computeArcLengthInRoI(roi);
184  float theoreticalValue = 0.f;
185  bool isValueOK = equal(arcLengthCircle, theoreticalValue);
186  std::string statusTest;
187  if (isValueOK) {
188  statusTest = "SUCCESS";
189  }
190  else {
191  statusTest = "FAILED";
192  }
193  std::cout << "Test with circle touching the left border, all the circle is hidden." << std::endl;
194  std::cout << "\tarc length =" << arcLengthCircle << std::endl;
195  std::cout << "\ttheoretical length =" << theoreticalValue << std::endl;
196  std::cout << "\ttest status = " << statusTest << std::endl;
197 
198  hasSucceeded &= isValueOK;
199  }
200 
201  // Test with intersections with the right border, more than half a circle visible
202  {
203  // Formula: uc = OFFSET + WIDTH - RADIUS * cos(theta)
204  // theta := PI / 3
205  float uc = OFFSET + 616.f;
206  float vc = OFFSET + 100.f;
207  vpImageCircle circle(vpImagePoint(vc, uc), RADIUS);
208  float arcLengthCircle = circle.computeArcLengthInRoI(roi);
209  float theoreticalValue = 4.f * M_PIf * RADIUS /3.f;
210  bool isValueOK = equal(arcLengthCircle, theoreticalValue);
211  std::string statusTest;
212  if (isValueOK) {
213  statusTest = "SUCCESS";
214  }
215  else {
216  statusTest = "FAILED";
217  }
218  std::cout << "Test intersection right border, more than half a circle visible." << std::endl;
219  std::cout << "\tarc length =" << arcLengthCircle << std::endl;
220  std::cout << "\ttheoretical length =" << theoreticalValue << std::endl;
221  std::cout << "\ttest status = " << statusTest << std::endl;
222 
223  hasSucceeded &= isValueOK;
224  }
225 
226  // Test with intersections with the right border, less than half a circle visible
227  {
228  // Formula: uc = OFFSET + WIDTH - RADIUS * cos(theta)
229  // theta := 2 * PI / 3
230  float uc = OFFSET + 664.f;
231  float vc = OFFSET + 100.f;
232  vpImageCircle circle(vpImagePoint(vc, uc), RADIUS);
233  float arcLengthCircle = circle.computeArcLengthInRoI(roi);
234  float theoreticalValue = 2.f * M_PIf * RADIUS /3.f;
235  bool isValueOK = equal(arcLengthCircle, theoreticalValue);
236  std::string statusTest;
237  if (isValueOK) {
238  statusTest = "SUCCESS";
239  }
240  else {
241  statusTest = "FAILED";
242  }
243  std::cout << "Test intersection right border, less than half a circle visible." << std::endl;
244  std::cout << "\tarc length =" << arcLengthCircle << std::endl;
245  std::cout << "\ttheoretical length =" << theoreticalValue << std::endl;
246  std::cout << "\ttest status = " << statusTest << std::endl;
247 
248  hasSucceeded &= isValueOK;
249  }
250 
251  // Test with circle touching the right border, all the circle is visible
252  {
253  // Formula: uc = OFFSET + WIDTH - RADIUS * cos(theta)
254  // theta := 0
255  float uc = OFFSET + WIDTH - RADIUS;
256  float vc = OFFSET + 100.f;
257  vpImageCircle circle(vpImagePoint(vc, uc), RADIUS);
258  float arcLengthCircle = circle.computeArcLengthInRoI(roi);
259  float theoreticalValue = 2.f * M_PIf * RADIUS;
260  bool isValueOK = equal(arcLengthCircle, theoreticalValue);
261  std::string statusTest;
262  if (isValueOK) {
263  statusTest = "SUCCESS";
264  }
265  else {
266  statusTest = "FAILED";
267  }
268  std::cout << "Test with circle touching the right border, all the circle is visible." << std::endl;
269  std::cout << "\tarc length =" << arcLengthCircle << std::endl;
270  std::cout << "\ttheoretical length =" << theoreticalValue << std::endl;
271  std::cout << "\ttest status = " << statusTest << std::endl;
272 
273  hasSucceeded &= isValueOK;
274  }
275 
276  // Test with circle touching the right border, all the circle is hidden
277  {
278  // Formula: uc = OFFSET + WIDTH - RADIUS * cos(theta)
279  // theta := 0
280  float uc = OFFSET + WIDTH + RADIUS;
281  float vc = OFFSET + 100.f;
282  vpImageCircle circle(vpImagePoint(vc, uc), RADIUS);
283  float arcLengthCircle = circle.computeArcLengthInRoI(roi);
284  float theoreticalValue = 0.f;
285  bool isValueOK = equal(arcLengthCircle, theoreticalValue);
286  std::string statusTest;
287  if (isValueOK) {
288  statusTest = "SUCCESS";
289  }
290  else {
291  statusTest = "FAILED";
292  }
293  std::cout << "Test with circle touching the right border, all the circle is hidden." << std::endl;
294  std::cout << "\tarc length =" << arcLengthCircle << std::endl;
295  std::cout << "\ttheoretical length =" << theoreticalValue << std::endl;
296  std::cout << "\ttest status = " << statusTest << std::endl;
297 
298  hasSucceeded &= isValueOK;
299  }
300 
301  // Test with intersections with the top border, more than half a circle visible
302  {
303  // v = vc - r sin(theta)
304  // Formula: vc = OFFSET + RADIUS * sin(theta)
305  float theta = M_PIf / 3.f;
306  float uc = OFFSET + 100.f;
307  float vc = OFFSET + RADIUS * sin(theta);
308  vpImageCircle circle(vpImagePoint(vc, uc), RADIUS);
309  float arcLengthCircle = circle.computeArcLengthInRoI(roi);
310  float theoreticalValue = 5.f * M_PIf * RADIUS /3.f;
311  bool isValueOK = equal(arcLengthCircle, theoreticalValue);
312  std::string statusTest;
313  if (isValueOK) {
314  statusTest = "SUCCESS";
315  }
316  else {
317  statusTest = "FAILED";
318  }
319  std::cout << "Test intersection top border, more than half a circle visible." << std::endl;
320  std::cout << "\tarc length =" << arcLengthCircle << std::endl;
321  std::cout << "\ttheoretical length =" << theoreticalValue << std::endl;
322  std::cout << "\ttest status = " << statusTest << std::endl;
323 
324  hasSucceeded &= isValueOK;
325  }
326 
327  // Test with intersections with the top border, less than half a circle visible
328  {
329  // v = vc - r sin(theta)
330  // Formula: vc = OFFSET + RADIUS * sin(theta)
331  float theta = -2.f * M_PIf/3.f;
332  float uc = OFFSET + 100.f;
333  float vc = OFFSET + RADIUS * std::sin(theta);
334  vpImageCircle circle(vpImagePoint(vc, uc), RADIUS);
335  float arcLengthCircle = circle.computeArcLengthInRoI(roi);
336  float theoreticalValue = M_PIf * RADIUS /3.f;
337  bool isValueOK = equal(arcLengthCircle, theoreticalValue);
338  std::string statusTest;
339  if (isValueOK) {
340  statusTest = "SUCCESS";
341  }
342  else {
343  statusTest = "FAILED";
344  }
345  std::cout << "Test intersection top border, less than half a circle visible." << std::endl;
346  std::cout << "\tarc length =" << arcLengthCircle << std::endl;
347  std::cout << "\ttheoretical length =" << theoreticalValue << std::endl;
348  std::cout << "\ttest status = " << statusTest << std::endl;
349 
350  hasSucceeded &= isValueOK;
351  }
352 
353  // Test with circle touching the top border, all the circle is visible
354  {
355  // v = vc - r sin(theta)
356  // Formula: vc = OFFSET + RADIUS * sin(theta)
357  float theta = M_PI_2f;
358  float uc = OFFSET + 100.f;
359  float vc = OFFSET + RADIUS * sin(theta);
360  vpImageCircle circle(vpImagePoint(vc, uc), RADIUS);
361  float arcLengthCircle = circle.computeArcLengthInRoI(roi);
362  float theoreticalValue = 2.f * M_PIf * RADIUS;
363  bool isValueOK = equal(arcLengthCircle, theoreticalValue);
364  std::string statusTest;
365  if (isValueOK) {
366  statusTest = "SUCCESS";
367  }
368  else {
369  statusTest = "FAILED";
370  }
371  std::cout << "Test with circle touching the top border, all the circle is visible." << std::endl;
372  std::cout << "\tarc length =" << arcLengthCircle << std::endl;
373  std::cout << "\ttheoretical length =" << theoreticalValue << std::endl;
374  std::cout << "\ttest status = " << statusTest << std::endl;
375 
376  hasSucceeded &= isValueOK;
377  }
378 
379  // Test with circle touching the top border, all the circle is hidden
380  {
381  // v = vc - r sin(theta)
382  // Formula: vc = OFFSET + RADIUS * sin(theta)
383  float theta = -M_PI_2f;
384  float uc = OFFSET + 100.f;
385  float vc = OFFSET + RADIUS * sin(theta);
386  vpImageCircle circle(vpImagePoint(vc, uc), RADIUS);
387  float arcLengthCircle = circle.computeArcLengthInRoI(roi);
388  float theoreticalValue = 0.f;
389  bool isValueOK = equal(arcLengthCircle, theoreticalValue);
390  std::string statusTest;
391  if (isValueOK) {
392  statusTest = "SUCCESS";
393  }
394  else {
395  statusTest = "FAILED";
396  }
397  std::cout << "Test with circle touching the top border, all the circle is hidden." << std::endl;
398  std::cout << "\tarc length =" << arcLengthCircle << std::endl;
399  std::cout << "\ttheoretical length =" << theoreticalValue << std::endl;
400  std::cout << "\ttest status = " << statusTest << std::endl;
401 
402  hasSucceeded &= isValueOK;
403  }
404 
405  // Test with intersections with the bottom border, more than half a circle visible
406  {
407  // v = vc - r sin(theta)
408  // Formula: vc = OFFSET + HEIGHT + RADIUS * sin(theta)
409  float theta = -M_PIf / 3.f;
410  float uc = OFFSET + 100.f;
411  float vc = OFFSET + HEIGHT + RADIUS * std::sin(theta);
412  vpImageCircle circle(vpImagePoint(vc, uc), RADIUS);
413  float arcLengthCircle = circle.computeArcLengthInRoI(roi);
414  float theoreticalValue = 5.f * M_PIf * RADIUS /3.f;
415  bool isValueOK = equal(arcLengthCircle, theoreticalValue);
416  std::string statusTest;
417  if (isValueOK) {
418  statusTest = "SUCCESS";
419  }
420  else {
421  statusTest = "FAILED";
422  }
423  std::cout << "Test intersection bottom border, more than half a circle visible." << std::endl;
424  std::cout << "\tarc length =" << arcLengthCircle << std::endl;
425  std::cout << "\ttheoretical length =" << theoreticalValue << std::endl;
426  std::cout << "\ttest status = " << statusTest << std::endl;
427 
428  hasSucceeded &= isValueOK;
429  }
430 
431  // Test with intersections with the bottom border, less than half a circle visible
432  {
433  // v = vc - r sin(theta)
434  // Formula: vc = OFFSET + HEIGHT + RADIUS * sin(theta)
435  float theta = M_PIf / 3.f;
436  float uc = OFFSET + 100.f;
437  float vc = OFFSET + HEIGHT + RADIUS * std::sin(theta);
438  vpImageCircle circle(vpImagePoint(vc, uc), RADIUS);
439  float arcLengthCircle = circle.computeArcLengthInRoI(roi);
440  float theoreticalValue = M_PIf * RADIUS /3.f;
441  bool isValueOK = equal(arcLengthCircle, theoreticalValue);
442  std::string statusTest;
443  if (isValueOK) {
444  statusTest = "SUCCESS";
445  }
446  else {
447  statusTest = "FAILED";
448  }
449  std::cout << "Test intersection bottom border, less than half a circle visible." << std::endl;
450  std::cout << "\tarc length =" << arcLengthCircle << std::endl;
451  std::cout << "\ttheoretical length =" << theoreticalValue << std::endl;
452  std::cout << "\ttest status = " << statusTest << std::endl;
453 
454  hasSucceeded &= isValueOK;
455  }
456 
457  // Test with circle touching the bottom border, all the circle is visible
458  {
459  // Formula: vc = OFFSET + HEIGHT - RADIUS * sin(theta)
460  float uc = OFFSET + 100.f;
461  float vc = OFFSET + HEIGHT - RADIUS;
462  vpImageCircle circle(vpImagePoint(vc, uc), RADIUS);
463  float arcLengthCircle = circle.computeArcLengthInRoI(roi);
464  float theoreticalValue = 2.f * M_PIf * RADIUS;
465  bool isValueOK = equal(arcLengthCircle, theoreticalValue);
466  std::string statusTest;
467  if (isValueOK) {
468  statusTest = "SUCCESS";
469  }
470  else {
471  statusTest = "FAILED";
472  }
473  std::cout << "Test with circle touching the bottom border, all the circle is visible." << std::endl;
474  std::cout << "\tarc length =" << arcLengthCircle << std::endl;
475  std::cout << "\ttheoretical length =" << theoreticalValue << std::endl;
476  std::cout << "\ttest status = " << statusTest << std::endl;
477 
478  hasSucceeded &= isValueOK;
479  }
480 
481  // Test with circle touching the bottom border, all the circle is hidden
482  {
483  // Formula: vc = OFFSET + HEIGHT + RADIUS * sin(theta)
484  float uc = OFFSET + 100.f;
485  float vc = OFFSET + HEIGHT + RADIUS;
486  vpImageCircle circle(vpImagePoint(vc, uc), RADIUS);
487  float arcLengthCircle = circle.computeArcLengthInRoI(roi);
488  float theoreticalValue = 0.f;
489  bool isValueOK = equal(arcLengthCircle, theoreticalValue);
490  std::string statusTest;
491  if (isValueOK) {
492  statusTest = "SUCCESS";
493  }
494  else {
495  statusTest = "FAILED";
496  }
497  std::cout << "Test with circle touching the bottom border, all the circle is hidden." << std::endl;
498  std::cout << "\tarc length =" << arcLengthCircle << std::endl;
499  std::cout << "\ttheoretical length =" << theoreticalValue << std::endl;
500  std::cout << "\ttest status = " << statusTest << std::endl;
501 
502  hasSucceeded &= isValueOK;
503  }
504 
505  // Test with intersections with the top and the left border, crossing each axis once in the RoI
506  {
507  // Formula: u_cross_top_max = uc + r cos (theta_u_top_max) >= umin ; vmin = vc - r sin(theta_u_top_max)
508  // Formula: umin = uc + r cos(theta_v_max) ; v = vc - r sin(theta_v_max) >= vmin
509  // Choice: theta_u_top_max - theta_v_max = pi / 2 => for theta_u_top_max = 0 theta_v_max = -pi/2
510  // => uc = umin - r cos(theta_v_max) vc = vmin + r sin(theta_u_top_max)
511  float uc = OFFSET;
512  float vc = OFFSET;
513  vpImageCircle circle(vpImagePoint(vc, uc), RADIUS);
514  float arcLengthCircle = circle.computeArcLengthInRoI(roi);
515  float theoreticalValue = M_PI_2f * RADIUS;
516  bool isValueOK = equal(arcLengthCircle, theoreticalValue);
517  std::string statusTest;
518  if (isValueOK) {
519  statusTest = "SUCCESS";
520  }
521  else {
522  statusTest = "FAILED";
523  }
524  std::cout << "Test with intersections with the top and the left border, crossing each axis once in the RoI." << std::endl;
525  std::cout << "\tarc length =" << arcLengthCircle << std::endl;
526  std::cout << "\ttheoretical length =" << theoreticalValue << std::endl;
527  std::cout << "\ttest status = " << statusTest << std::endl;
528 
529  hasSucceeded &= isValueOK;
530  }
531 
532  // Test with intersections with the top and the left border
533  // but crossing only the left axis in the RoI
534  {
535  // (1): u_cross_top_min = uc + rcos(theta_u_top_min) <= umin ; vmin = vc - r sin(theta_u_top_min)
536  // (2): u_cross_top_max = uc + rcos(theta_u_top_max) <= umin ; vmin = vc - r sin(theta_u_top_max)
537  // (3): umin = uc + r cos(theta_v_min) ; v_cross_min = vc - r sin(theta_v_min) >= vmin && <= vmin + height
538  // (4): umin = uc + r cos(theta_v_max) ; v_cross_max = vc - r sin(theta_v_max) >= vmin && <= vmin + height
539  // (3) & (4) => uc = umin - r cos(theta_v_min) = umin - r cos(theta_v_max) <=> theta_v_min = - theta_v_max
540  // (3) & (4) => vc >= vmin + r sin(theta_v_min) && vc >= vmin + r sin (theta_v_max)
541  float theta_v_min = M_PIf / 4.f;
542  float uc = OFFSET - RADIUS * std::cos(theta_v_min);
543  float vc = OFFSET + RADIUS * std::sin(theta_v_min) + 1.f;
544  vc = std::max<float>(vc, OFFSET + RADIUS * std::sin(-theta_v_min) + 1.f);
545  vpImageCircle circle(vpImagePoint(vc, uc), RADIUS);
546  float arcLengthCircle = circle.computeArcLengthInRoI(roi);
547  float theoreticalValue = M_PI_2f * RADIUS;
548  bool isValueOK = equal(arcLengthCircle, theoreticalValue);
549  std::string statusTest;
550  if (isValueOK) {
551  statusTest = "SUCCESS";
552  }
553  else {
554  statusTest = "FAILED";
555  }
556  std::cout << "Test with intersections with the top and the left border but crossing only the left axis in the RoI." << std::endl;
557  std::cout << "\tarc length =" << arcLengthCircle << std::endl;
558  std::cout << "\ttheoretical length =" << theoreticalValue << std::endl;
559  std::cout << "\ttest status = " << statusTest << std::endl;
560 
561  hasSucceeded &= isValueOK;
562  }
563 
564  // Test with intersections with the top and the left border
565  // but crossing only the top axis in the RoI
566  {
567  // (1): u_cross_top_min = uc + rcos(theta_u_top_min) >= umin ; vmin = vc - r sin(theta_u_top_min)
568  // (2): u_cross_top_max = uc + rcos(theta_u_top_max) >= umin ; vmin = vc - r sin(theta_u_top_max)
569  // (3): umin = uc + r cos(theta_v_min) ; v_cross_min = vc - r sin(theta_v_min) <= vmin
570  // (4): umin = uc + r cos(theta_v_max) ; v_cross_max = vc - r sin(theta_v_max) <= vmin
571  // (1) & (2) => vmin = vc - r sin (theta_u_top_min) = vc - r sin(theta_u_top_max) <=> theta_u_top_min = PI - theta_u_top_max
572  // (1) => uc + r cos(theta_u_top_min) >= umin <=> uc >= umin - r cos(theta_u_top_min)
573  // (2) => uc + r cos(theta_u_top_max) >= umin <=> uc >= umin - r cos(theta_u_top_max)
574 
575  float theta_u_top_min = -1.1f * M_PI_2f;
576  float uc = OFFSET - RADIUS * std::cos(theta_u_top_min) + 1.f;
577  uc = std::max<float>(uc, OFFSET - RADIUS * std::cos(M_PIf - theta_u_top_min) + 1.f);
578  float vc = OFFSET + RADIUS * std::sin(theta_u_top_min);
579  vpImageCircle circle(vpImagePoint(vc, uc), RADIUS);
580  float arcLengthCircle = circle.computeArcLengthInRoI(roi);
581  float theoreticalValue = 0.2f * M_PI_2f * RADIUS;
582  bool isValueOK = equal(arcLengthCircle, theoreticalValue);
583  std::string statusTest;
584  if (isValueOK) {
585  statusTest = "SUCCESS";
586  }
587  else {
588  statusTest = "FAILED";
589  }
590  std::cout << "Test with intersections with the top and the left border but crossing only the top axis in the RoI." << std::endl;
591  std::cout << "\tarc length =" << arcLengthCircle << std::endl;
592  std::cout << "\ttheoretical length =" << theoreticalValue << std::endl;
593  std::cout << "\ttest status = " << statusTest << std::endl;
594 
595  hasSucceeded &= isValueOK;
596  }
597 
598  // Test with intersections with the top and the left border
599  // crossing twice each axis
600  {
601  // (1): u_cross_top_min = uc + r cos(theta_u_top_min) >= umin ; vmin = vc - r sin(theta_u_top_min)
602  // (2): u_cross_top_max = uc + r cos(theta_u_top_max) >= umin ; vmin = vc - r sin(theta_u_top_max)
603  // (3): umin = uc + r cos(theta_v_min) ; v_cross_min = vc - r sin(theta_v_min) >= vmin
604  // (4): umin = uc + r cos(theta_v_max) ; v_cross_max = vc - r sin(theta_v_max) >= vmin
605  // (1) & (2) => vmin = vc - r sin(theta_u_top_min) = vc - r sin(theta_u_top_max) <=> theta_u_top_min = PI - theta_u_top_max
606  // (1) & (2) =>{ uc >= umin - r cos(theta_u_top_min) & { uc >= umin - r cos(PI - theta_u_top_min)
607  // (1) & (2) { vc = vmin + r sin(theta_u_top_min) & { vc = vmin + r sin(PI - theta_u_top_min)
608  // (3) & (4) =>{ uc = umin - r cos(theta_v_min) & { uc = umin - r cos(- theta_v_min)
609  // (3) & (4) { vc >= vmin - r sin(theta_v_min) & { vc >= vmin - r cos(- theta_v_min)
610 
611  float theta_u_top_min = 5.f * M_PIf / 8.f;
612  float theta_u_top_max = M_PIf - theta_u_top_min;
613  float uc = OFFSET - RADIUS * std::cos(theta_u_top_min) + 1.f;
614  uc = std::max<float>(uc, OFFSET - RADIUS * std::cos(M_PIf - theta_u_top_min) + 1.f);
615  float vc = OFFSET + RADIUS * std::sin(theta_u_top_min);
616  float theta_v_min = std::acos((OFFSET - uc)/RADIUS);
617  theta_v_min = vpMath::getAngleBetweenMinPiAndPi(theta_v_min);
618  float theta_v_max = -theta_v_min;
619  if (theta_v_max < 0) {
620  float temp = theta_v_max;
621  theta_v_max = theta_v_min;
622  theta_v_min = temp;
623  }
624  vpImageCircle circle(vpImagePoint(vc, uc), RADIUS);
625  float arcLengthCircle = circle.computeArcLengthInRoI(roi);
626  float theoreticalValue = ((theta_v_max - theta_u_top_min) + (theta_u_top_max - theta_v_min)) * RADIUS;
627  bool isValueOK = equal(arcLengthCircle, theoreticalValue);
628  std::string statusTest;
629  if (isValueOK) {
630  statusTest = "SUCCESS";
631  }
632  else {
633  statusTest = "FAILED";
634  }
635  std::cout << "Test with intersections with the top and the left border crossing twice each axis ." << std::endl;
636  std::cout << "\tarc length =" << arcLengthCircle << std::endl;
637  std::cout << "\ttheoretical length = " << theoreticalValue << std::endl;
638  std::cout << "\ttest status = " << statusTest << std::endl;
639 
640  hasSucceeded &= isValueOK;
641  }
642 
643  // Test with intersections with the top and the right border, crossing each axis once in the RoI
644  {
645  // (1): u_cross_top_min = uc + r cos(theta_u_top_min) <= umin + width ; vmin = vc - r sin(theta_u_top_min)
646  // (2): umin + width = uc + r cos(theta_v_min) ; v_cross_min = vc - r sin(theta_v_min) <= vmin
647  // (3): u_cross_top_max = uc + r cos(theta_u_top_max) >= umin + width ; vmin = vc - r sin(theta_u_top_max)
648  // (4): umin + width = uc + r cos(theta_v_max) ; v_cross_max = vc - r sin(theta_v_max) >= vmin
649  // Choice: for theta_u_top_min = 2PI/3 theta_v_max = -pi/2
650  // (4) => uc = umin + width - r cos(theta_v_max)
651  // (1) => vc = vmin + r sin(theta_u_top_min)
652  // (1) & (3) theta_u_top_min = PI - theta_u_top_max
653  // (2) & (4) theta_v_min = - theta_v_max
654  float theta_u_top_min = 2.f * M_PIf / 3.f;
655  float theta_v_max = -M_PI_2f;
656  float uc = OFFSET + WIDTH - RADIUS * std::cos(theta_v_max);
657  float vc = OFFSET + RADIUS * std::sin(theta_u_top_min);;
658  vpImageCircle circle(vpImagePoint(vc, uc), RADIUS);
659  float arcLengthCircle = circle.computeArcLengthInRoI(roi);
660  float theoreticalValue = (M_PI_2f + M_PIf / 3.f) * RADIUS;
661  bool isValueOK = equal(arcLengthCircle, theoreticalValue);
662  std::string statusTest;
663  if (isValueOK) {
664  statusTest = "SUCCESS";
665  }
666  else {
667  statusTest = "FAILED";
668  }
669  std::cout << "Test with intersections with the top and the right border, crossing each axis once in the RoI." << std::endl;
670  std::cout << "\tarc length =" << arcLengthCircle << std::endl;
671  std::cout << "\ttheoretical length =" << theoreticalValue << std::endl;
672  std::cout << "\ttest status = " << statusTest << std::endl;
673 
674  hasSucceeded &= isValueOK;
675  }
676 
677  // Test with intersections with the top and the right border,
678  // but crossing only the right border in the RoI
679  {
680  // (1): u_cross_top_min = uc + r cos(theta_u_top_min) >= umin + width ; vmin = vc - r sin(theta_u_top_min)
681  // (2): umin + width = uc + r cos(theta_v_min) ; v_cross_min = vc - r sin(theta_v_min) >= vmin
682  // (3): u_cross_top_max = uc + r cos(theta_u_top_max) >= umin + width ; vmin = vc - r sin(theta_u_top_max)
683  // (4): umin + width = uc + r cos(theta_v_max) ; v_cross_max = vc - r sin(theta_v_max) >= vmin
684  // (4) => uc = umin + width - r cos(theta_v_max)
685  // (1) => theta_u_top_min = asin((vc - vmin)/r) & uc + r cos(theta_u_top_min) >= umin + width <=> uc + r cos[asin((vc - vmin)/r)] >= umin + width
686  // (1) <=> asin((vc - vmin)/r) >= acos[(umin + width - uc)/r] <=> vc >= r sin(acos[(umin + width - uc)/r]) + vmin
687  // (1) & (3) theta_u_top_min = PI - theta_u_top_max
688  // (2) & (4) theta_v_min = - theta_v_max
689  float theta_v_max = -7.f * M_PIf / 8.f;
690  float theta_v_min = -theta_v_max;
691  float uc = OFFSET + WIDTH - RADIUS * std::cos(theta_v_max);
692  float vc = RADIUS * std::sin(std::acos((OFFSET + WIDTH - uc)/RADIUS)) + OFFSET + 1.f;
693  vpImageCircle circle(vpImagePoint(vc, uc), RADIUS);
694  float arcLengthCircle = circle.computeArcLengthInRoI(roi);
695  float theoreticalValue = (2.f * M_PIf - (theta_v_min - theta_v_max)) * RADIUS;
696  bool isValueOK = equal(arcLengthCircle, theoreticalValue);
697  std::string statusTest;
698  if (isValueOK) {
699  statusTest = "SUCCESS";
700  }
701  else {
702  statusTest = "FAILED";
703  }
704  std::cout << "Test with intersections with the top and the right border, but crossing only the right border in the RoI." << std::endl;
705  std::cout << "\tarc length =" << arcLengthCircle << std::endl;
706  std::cout << "\ttheoretical length =" << theoreticalValue << std::endl;
707  std::cout << "\ttest status = " << statusTest << std::endl;
708 
709  hasSucceeded &= isValueOK;
710  }
711 
712  // Test with intersections with the top and the right border,
713  // but crossing only the top border in the RoI
714  {
715  // (1): u_cross_top_min = uc + r cos(theta_u_top_min) <= umin + width ; vmin = vc - r sin(theta_u_top_min)
716  // (2): umin + width = uc + r cos(theta_v_min) ; v_cross_min = vc - r sin(theta_v_min) <= vmin
717  // (3): u_cross_top_max = uc + r cos(theta_u_top_max) <= umin + width ; vmin = vc - r sin(theta_u_top_max)
718  // (4): umin + width = uc + r cos(theta_v_max) ; v_cross_max = vc - r sin(theta_v_max) <= vmin
719  // (1) & (3) theta_u_top_min = PI - theta_u_top_max
720  // (2) & (4) theta_v_min = - theta_v_max
721  // Choice: theta_u_top_min = -0.9 * PI / 2
722  // (1) => vc = vmin + r sin(theta_u_top_min)
723  // (2) vc - r sin(theta_v_min) <= vmin => asin((vc - vmin)/r) <= theta_v_min
724  float theta_u_top_min = -0.9f * M_PI_2f;
725  float theta_u_top_max = M_PIf - theta_u_top_min;
726  theta_u_top_max = vpMath::getAngleBetweenMinPiAndPi(theta_u_top_max);
727  float vc = OFFSET + RADIUS * std::sin(theta_u_top_min);
728  float theta_v_min = std::asin((vc - OFFSET)/RADIUS) + 1.f;
729  float uc = OFFSET + WIDTH - RADIUS * std::cos(theta_v_min);
730  vpImageCircle circle(vpImagePoint(vc, uc), RADIUS);
731  float arcLengthCircle = circle.computeArcLengthInRoI(roi);
732  float theoreticalValue = std::abs(theta_u_top_min - theta_u_top_max) * RADIUS;
733  bool isValueOK = equal(arcLengthCircle, theoreticalValue);
734  std::string statusTest;
735  if (isValueOK) {
736  statusTest = "SUCCESS";
737  }
738  else {
739  statusTest = "FAILED";
740  }
741  std::cout << "Test with intersections with the top and the right border, but crossing only the top border in the RoI." << std::endl;
742  std::cout << "\tarc length =" << arcLengthCircle << std::endl;
743  std::cout << "\ttheoretical length =" << theoreticalValue << std::endl;
744  std::cout << "\ttest status = " << statusTest << std::endl;
745 
746  hasSucceeded &= isValueOK;
747  }
748 
749  // Test with intersections with the top and the left border
750  // crossing twice each axis
751  {
752  // (1): u_cross_top_min = uc + r cos(theta_u_top_min) < umin + width ; vmin = vc - r sin(theta_u_top_min)
753  // (2): umin + width = uc + r cos(theta_v_min) ; v_cross_min = vc - r sin(theta_v_min) >= vmin
754  // (3): u_cross_top_miax = uc + r cos(theta_u_top_max) <= umin + width; vmin = vc - r sin(theta_u_top_max)
755  // (4): umin + width = uc + r cos(theta_v_max) ; v_cross_max = vc - r sin(theta_v_max) > vmin
756  // (1) & (3) => vmin = vc - r sin(theta_u_top_min) = vc - r sin(theta_u_top_max) <=> theta_u_top_min = PI - theta_u_top_max
757  // (1) & (3) =>{ uc < umin + width - r cos(theta_u_top_min) & { uc <= umin + width - r cos(PI - theta_u_top_min)
758  // (1) & (3) { vc = vmin + r sin(theta_u_top_min) & { vc = vmin + r sin(PI - theta_u_top_min)
759  // (2) & (4) =>{ uc = umin - r cos(theta_v_min) & { uc = umin - r cos(- theta_v_min)
760  // (2) & (4) { vc >= vmin - r sin(theta_v_min) & { vc >= vmin - r cos(- theta_v_min)
761 
762  float theta_u_top_min = 5.f * M_PIf / 8.f;
763  float theta_u_top_max = M_PIf - theta_u_top_min;
764  float uc = OFFSET + WIDTH - RADIUS * std::cos(theta_u_top_min) - 1.f;
765  uc = std::min<float>(uc, OFFSET + WIDTH - RADIUS * std::cos(M_PIf - theta_u_top_min) - 1.f);
766  float vc = OFFSET + RADIUS * std::sin(theta_u_top_min);
767  float theta_v_min = std::acos((OFFSET + WIDTH - uc)/RADIUS);
768  theta_v_min = vpMath::getAngleBetweenMinPiAndPi(theta_v_min);
769  float theta_v_max = -theta_v_min;
770  if (theta_v_min < 0) {
771  float temp = theta_v_min;
772  theta_v_min = theta_v_max;
773  theta_v_max = temp;
774  }
775  vpImageCircle circle(vpImagePoint(vc, uc), RADIUS);
776  float arcLengthCircle = circle.computeArcLengthInRoI(roi);
777  float theoreticalValue = (2.f * M_PIf - ((theta_u_top_min - theta_u_top_max) + (theta_v_min - theta_v_max))) * RADIUS;
778  bool isValueOK = equal(arcLengthCircle, theoreticalValue);
779  std::string statusTest;
780  if (isValueOK) {
781  statusTest = "SUCCESS";
782  }
783  else {
784  statusTest = "FAILED";
785  }
786  std::cout << "Test with intersections with the top and the left border crossing twice each axis ." << std::endl;
787  std::cout << "\tarc length =" << arcLengthCircle << std::endl;
788  std::cout << "\ttheoretical length = " << theoreticalValue << std::endl;
789  std::cout << "\ttest status = " << statusTest << std::endl;
790 
791  hasSucceeded &= isValueOK;
792  }
793 
794  // Test with intersections with the bottom and the left border, crossing each axis once in the RoI
795  {
796  // (1): u_cross_bot_min = uc + r cos(theta_u_bot_min) <= umin ; vmin + height = vc - r sin(theta_u_bot_min)
797  // (2): umin = uc + r cos(theta_v_min) ; v_cross_min = vc - r sin(theta_v_min) <= vmin + height
798  // (3): u_cross_bot_max = uc + r cos(theta_u_bot_max) >= umin ; vmin + height = vc - r sin(theta_u_bot_max)
799  // (4): umin = uc + r cos(theta_v_max) ; v_cross_max = vc - r sin(theta_v_max) >= vmin + height
800  // Choice: for theta_v_min = PI/2 theta_u_bot_max = -PI/3
801  // (2) => uc = umin - r cos(theta_v_min)
802  // (3) => vc = vmin + height + r sin(theta_u_bot_max)
803  // (1) & (3) theta_u_bot_min = PI - theta_u_bot_max
804  // (2) & (4) theta_v_min = - theta_v_max
805  float theta_v_min = M_PI_2f;
806  float theta_u_bot_max = -M_PIf / 3.f;
807  float uc = OFFSET - RADIUS * std::cos(theta_v_min);
808  float vc = OFFSET + HEIGHT + RADIUS * std::sin(theta_u_bot_max);;
809  vpImageCircle circle(vpImagePoint(vc, uc), RADIUS);
810  float arcLengthCircle = circle.computeArcLengthInRoI(roi);
811  float theoreticalValue = (M_PI_2f + M_PIf / 3.f) * RADIUS;
812  bool isValueOK = equal(arcLengthCircle, theoreticalValue);
813  std::string statusTest;
814  if (isValueOK) {
815  statusTest = "SUCCESS";
816  }
817  else {
818  statusTest = "FAILED";
819  }
820  std::cout << "Test with intersections with the bottom and the left border, crossing each axis once in the RoI." << std::endl;
821  std::cout << "\tarc length =" << arcLengthCircle << std::endl;
822  std::cout << "\ttheoretical length =" << theoreticalValue << std::endl;
823  std::cout << "\ttest status = " << statusTest << std::endl;
824 
825  hasSucceeded &= isValueOK;
826  }
827 
828  // Test with intersections with the bottom and the left border
829  // but crossing only the left border in the RoI
830  {
831  // (1): u_cross_bot_min = uc + r cos(theta_u_bot_min) <= umin ; vmin + height = vc - r sin(theta_u_bot_min)
832  // (2): umin = uc + r cos(theta_v_min) ; v_cross_min = vc - r sin(theta_v_min) <= vmin + height
833  // (3): u_cross_bot_max = uc + r cos(theta_u_bot_max) <= umin ; vmin + height = vc - r sin(theta_u_bot_max)
834  // (4): umin = uc + r cos(theta_v_max) ; v_cross_max = vc - r sin(theta_v_max) <= vmin + height
835  // Choice: for theta_v_min = PI/8
836  // (2) => uc = umin - r cos(theta_v_min)
837  // (2) => vc <= vmin + height + r sin(theta_v_min)
838  // (4) => vc <= vmin + height + r sin(theta_v_max)
839  // (1) & (3) theta_u_bot_min = PI - theta_u_bot_max
840  // (2) & (4) theta_v_min = - theta_v_max
841  float theta_v_min = M_PI_4f / 2.f;
842  float theta_v_max = -theta_v_min;
843  float uc = OFFSET - RADIUS * std::cos(theta_v_min);
844  float vc = std::min<float>(OFFSET + HEIGHT + RADIUS * std::sin(theta_v_min) - 1.f, OFFSET + HEIGHT + RADIUS * std::sin(theta_v_max) - 1.f);
845  vpImageCircle circle(vpImagePoint(vc, uc), RADIUS);
846  float arcLengthCircle = circle.computeArcLengthInRoI(roi);
847  float theoreticalValue = (2.f * theta_v_min) * RADIUS;
848  bool isValueOK = equal(arcLengthCircle, theoreticalValue);
849  std::string statusTest;
850  if (isValueOK) {
851  statusTest = "SUCCESS";
852  }
853  else {
854  statusTest = "FAILED";
855  }
856  std::cout << "Test with intersections with the bottom and the left border, but crossing only the left border in the RoI." << std::endl;
857  std::cout << "\tarc length =" << arcLengthCircle << std::endl;
858  std::cout << "\ttheoretical length =" << theoreticalValue << std::endl;
859  std::cout << "\ttest status = " << statusTest << std::endl;
860 
861  hasSucceeded &= isValueOK;
862  }
863 
864  // Test with intersections with the bottom and the left border
865  // but crossing only the bottom border in the RoI
866  {
867  // (1): u_cross_bot_min = uc + r cos(theta_u_bot_min) >= umin ; vmin + height = vc - r sin(theta_u_bot_min)
868  // (2): umin = uc + r cos(theta_v_min) ; v_cross_min = vc - r sin(theta_v_min) >= vmin + height
869  // (3): u_cross_bot_max = uc + r cos(theta_u_bot_max) >= umin ; vmin + height = vc - r sin(theta_u_bot_max)
870  // (4): umin = uc + r cos(theta_v_max) ; v_cross_max = vc - r sin(theta_v_max) >= vmin + height
871  // Choice: for theta_u_bot_min = 5 PI/8
872  // (1) => vc = vmin + height + r sin(theta_u_bot_min)
873  // (1) => uc >= umin - r cos(theta_u_bot_min)
874  // (1) => uc >= umin - r cos(theta_u_bot_max)
875  // (1) & (3) theta_u_bot_min = PI - theta_u_bot_max
876  // (2) & (4) theta_v_min = - theta_v_max
877  float theta_u_bot_min = 5.f * M_PI_4f / 2.f;
878  float theta_u_bot_max = M_PIf - theta_u_bot_min;
879  float vc = OFFSET + HEIGHT + RADIUS * std::sin(theta_u_bot_min);
880  float uc = std::max<float>(OFFSET - RADIUS * std::cos(theta_u_bot_min) + 1.f, OFFSET - RADIUS * std::cos(theta_u_bot_max) + 1.f);
881  vpImageCircle circle(vpImagePoint(vc, uc), RADIUS);
882  float arcLengthCircle = circle.computeArcLengthInRoI(roi);
883  float theoreticalValue = (theta_u_bot_min - theta_u_bot_max) * RADIUS;
884  bool isValueOK = equal(arcLengthCircle, theoreticalValue);
885  std::string statusTest;
886  if (isValueOK) {
887  statusTest = "SUCCESS";
888  }
889  else {
890  statusTest = "FAILED";
891  }
892  std::cout << "Test with intersections with the bottom and the left border, but crossing only the bottom border in the RoI." << std::endl;
893  std::cout << "\tarc length =" << arcLengthCircle << std::endl;
894  std::cout << "\ttheoretical length =" << theoreticalValue << std::endl;
895  std::cout << "\ttest status = " << statusTest << std::endl;
896 
897  hasSucceeded &= isValueOK;
898  }
899 
900  // Test with intersections with the bottom and the left border
901  // crossing each axis twice in the RoI
902  {
903  // (1): u_cross_bot_min = uc + r cos(theta_u_bot_min) >= umin ; vmin + height = vc - r sin(theta_u_bot_min)
904  // (2): umin = uc + r cos(theta_v_min) ; v_cross_min = vc - r sin(theta_v_min) < vmin + height
905  // (3): u_cross_bot_max = uc + r cos(theta_u_bot_max) > umin ; vmin + height = vc - r sin(theta_u_bot_max)
906  // (4): umin = uc + r cos(theta_v_max) ; v_cross_max = vc - r sin(theta_v_max) <= vmin + height
907  // (1) & (3) => uc >= umin - r cos(theta_u_bot_min) & uc > umin - r cos(theta_u_bot_max)
908  // (1) & (3) => vc = vmin + height + r sin(theta_u_bot_min) & vc = vmin + height + r sin(PI - theta_u_bot_min)
909  // (2) & (4) => uc = umin - r cos(theta_v_min) & uc = umin - r cos(-theta_v_min)
910  // (2) & (4) => vc < vmin + height + r sin(theta_v_min) & vc < vmin + height + r sin(-theta_v_min)
911  // (1) & (3) theta_u_bot_min = PI - theta_u_bot_max
912  // (2) & (4) theta_v_min = - theta_v_max
913  float theta_u_bot_min = -5.f * M_PIf / 8.f;
914  float theta_u_bot_max = M_PIf - theta_u_bot_min;
915  theta_u_bot_max = vpMath::getAngleBetweenMinPiAndPi(theta_u_bot_max);
916  float theta_v_min = 7.f * M_PIf / 8.f;
917  float theta_v_max = -theta_v_min;
918  float vc = OFFSET + HEIGHT + RADIUS * std::sin(theta_u_bot_min);
919  float uc = OFFSET - RADIUS * std::cos(theta_v_min);
920  vpImageCircle circle(vpImagePoint(vc, uc), RADIUS);
921  float arcLengthCircle = circle.computeArcLengthInRoI(roi);
922  float theoreticalValue = ((theta_v_min - theta_u_bot_max) + (theta_u_bot_min - theta_v_max)) * RADIUS;
923  bool isValueOK = equal(arcLengthCircle, theoreticalValue);
924  std::string statusTest;
925  if (isValueOK) {
926  statusTest = "SUCCESS";
927  }
928  else {
929  statusTest = "FAILED";
930  }
931  std::cout << "Test with intersections with the bottom and the left border, crossing each axis twice in the RoI." << std::endl;
932  std::cout << "\tarc length =" << arcLengthCircle << std::endl;
933  std::cout << "\ttheoretical length =" << theoreticalValue << std::endl;
934  std::cout << "\ttest status = " << statusTest << std::endl;
935 
936  hasSucceeded &= isValueOK;
937  }
938 
939  // Test with intersections with the bottom and the right border, crossing each axis once in the RoI
940  {
941  // (1): u_cross_bot_min = uc + r cos(theta_u_bot_min) <= umin + width ; vmin + height = vc - r sin(theta_u_bot_min)
942  // (2): umin + width = uc + r cos(theta_v_min) ; v_cross_min = vc - r sin(theta_v_min) <= vmin + height
943  // (3): u_cross_bot_max = uc + r cos(theta_u_bot_max) >= umin + width ; vmin + height = vc - r sin(theta_u_bot_max)
944  // (4): umin + width = uc + r cos(theta_v_max) ; v_cross_max = vc - r sin(theta_v_max) >= vmin + height
945  // Choice: for theta_u_bot_min = -2PI/3 theta_v_min = PI/2
946  // (2) => uc = umin + width - r cos(theta_v_min)
947  // (1) => vc = vmin + height + r sin(theta_u_bot_min)
948  // (1) & (3) theta_u_bot_min = PI - theta_u_bot_max
949  // (2) & (4) theta_v_min = - theta_v_max
950  float theta_u_bot_min = -2.f * M_PIf / 3.f;
951  float theta_v_min = M_PI_2f;
952  float uc = OFFSET + WIDTH - RADIUS * std::cos(theta_v_min);
953  float vc = OFFSET + HEIGHT + RADIUS * std::sin(theta_u_bot_min);;
954  vpImageCircle circle(vpImagePoint(vc, uc), RADIUS);
955  float arcLengthCircle = circle.computeArcLengthInRoI(roi);
956  float theoreticalValue = (M_PI_2f + M_PIf / 3.f) * RADIUS;
957  bool isValueOK = equal(arcLengthCircle, theoreticalValue);
958  std::string statusTest;
959  if (isValueOK) {
960  statusTest = "SUCCESS";
961  }
962  else {
963  statusTest = "FAILED";
964  }
965  std::cout << "Test with intersections with the bottom and the right border, crossing each axis once in the RoI." << std::endl;
966  std::cout << "\tarc length =" << arcLengthCircle << std::endl;
967  std::cout << "\ttheoretical length =" << theoreticalValue << std::endl;
968  std::cout << "\ttest status = " << statusTest << std::endl;
969 
970  hasSucceeded &= isValueOK;
971  }
972 
973  // Test with intersections with the bottom and the right border,
974  // crossing only the right axis in the RoI
975  {
976  // (1): u_cross_bot_min = uc + r cos(theta_u_bot_min) <= umin + width ; vmin + height = vc - r sin(theta_u_bot_min)
977  // (2): umin + width = uc + r cos(theta_v_min) ; v_cross_min = vc - r sin(theta_v_min) <= vmin + height
978  // (3): u_cross_bot_max = uc + r cos(theta_u_bot_max) >= umin + width ; vmin + height = vc - r sin(theta_u_bot_max)
979  // (4): umin + width = uc + r cos(theta_v_max) ; v_cross_max = vc - r sin(theta_v_max) >= vmin + height
980  // Choice: for theta_v_min = 5*PI/6
981  // (2) => uc = umin + width - r cos(theta_v_min)
982  // (2) & (4) => vc <= vmin + height + r sin(theta_v_min) & vc <= vmin + height + r sin(-theta_v_min)
983  // (1) & (3) theta_u_bot_min = PI - theta_u_bot_max
984  // (2) & (4) theta_v_min = - theta_v_max
985  float theta_v_min = 5.f * M_PIf / 6.f;
986  float uc = OFFSET + WIDTH - RADIUS * std::cos(theta_v_min);
987  float vc = std::min<float>(OFFSET + HEIGHT + RADIUS * std::sin(theta_v_min) - 1.f, OFFSET + HEIGHT + RADIUS * std::sin(-theta_v_min) - 1.f);
988  vpImageCircle circle(vpImagePoint(vc, uc), RADIUS);
989  float arcLengthCircle = circle.computeArcLengthInRoI(roi);
990  float theoreticalValue = (M_PIf / 3.f) * RADIUS; // <=> 2.f * M_PIf / 6.f
991  bool isValueOK = equal(arcLengthCircle, theoreticalValue);
992  std::string statusTest;
993  if (isValueOK) {
994  statusTest = "SUCCESS";
995  }
996  else {
997  statusTest = "FAILED";
998  }
999  std::cout << "Test with intersections with the bottom and the right border, crossing only the right axis in the RoI in the RoI." << std::endl;
1000  std::cout << "\tarc length =" << arcLengthCircle << std::endl;
1001  std::cout << "\ttheoretical length =" << theoreticalValue << std::endl;
1002  std::cout << "\ttest status = " << statusTest << std::endl;
1003 
1004  hasSucceeded &= isValueOK;
1005  }
1006 
1007  // Test with intersections with the bottom and the right border,
1008  // crossing only the bottom axis in the RoI
1009  {
1010  // (1): u_cross_bot_min = uc + r cos(theta_u_bot_min) < umin + width ; vmin + height = vc - r sin(theta_u_bot_min)
1011  // (2): umin + width = uc + r cos(theta_v_min) ; v_cross_min = vc - r sin(theta_v_min) >= vmin + height
1012  // (3): u_cross_bot_max = uc + r cos(theta_u_bot_max) <= umin + width ; vmin + height = vc - r sin(theta_u_bot_max)
1013  // (4): umin + width = uc + r cos(theta_v_max) ; v_cross_max = vc - r sin(theta_v_max) >= vmin + height
1014  // Choice: for theta_u_bot_min = 4*PI/6
1015  // (1) => vc = vmin + height + r cos(theta_u_bot_min)
1016  // (1) & (3) => uc < umin + width - r cos(theta_u_bot_min) & uc <= umin + width - r cos(PI - theta_u_bot_min)
1017  // (1) & (3) theta_u_bot_min = PI - theta_u_bot_max
1018  // (2) & (4) theta_v_min = - theta_v_max
1019  float theta_u_bot_min = 4.f * M_PIf / 6.f;
1020  float vc = OFFSET + HEIGHT + RADIUS * std::sin(theta_u_bot_min);
1021  float uc = std::min<float>(OFFSET + WIDTH - RADIUS * std::cos(theta_u_bot_min) - 1.f, OFFSET + WIDTH - RADIUS * std::cos(M_PIf -theta_u_bot_min) - 1.f);
1022  vpImageCircle circle(vpImagePoint(vc, uc), RADIUS);
1023  float arcLengthCircle = circle.computeArcLengthInRoI(roi);
1024  float theoreticalValue = (M_PIf / 3.f) * RADIUS; // <=> 2.f * M_PIf / 6.f
1025  bool isValueOK = equal(arcLengthCircle, theoreticalValue);
1026  std::string statusTest;
1027  if (isValueOK) {
1028  statusTest = "SUCCESS";
1029  }
1030  else {
1031  statusTest = "FAILED";
1032  }
1033  std::cout << "Test with intersections with the bottom and the right border, crossing only the bottom axis in the RoI in the RoI." << std::endl;
1034  std::cout << "\tarc length =" << arcLengthCircle << std::endl;
1035  std::cout << "\ttheoretical length =" << theoreticalValue << std::endl;
1036  std::cout << "\ttest status = " << statusTest << std::endl;
1037 
1038  hasSucceeded &= isValueOK;
1039  }
1040 
1041  // Test with intersections with the bottom and the right border
1042  // crossing each axis twice in the RoI
1043  {
1044  // (1): u_cross_bot_min = uc + r cos(theta_u_bot_min) < umin + width ; vmin + height = vc - r sin(theta_u_bot_min)
1045  // (2): umin + width = uc + r cos(theta_v_min) ; v_cross_min = vc - r sin(theta_v_min) < vmin + height
1046  // (3): u_cross_bot_max = uc + r cos(theta_u_bot_max) <= umin + width ; vmin + height = vc - r sin(theta_u_bot_max)
1047  // (4): umin + width = uc + r cos(theta_v_max) ; v_cross_max = vc - r sin(theta_v_max) <= vmin + height
1048  // (1) & (3) => uc < umin + width - r cos(theta_u_bot_min) & uc <= umin + width - r cos(PI - theta_u_bot_min)
1049  // (1) & (3) => vc = vmin + height + r sin(theta_u_bot_min) & vc = vmin + height + r sin(PI - theta_u_bot_min)
1050  // (2) & (4) => uc = umin + width - r cos(theta_v_min) & uc = umin + width - r cos(-theta_v_min)
1051  // (2) & (4) => vc < vmin + height + r sin(theta_v_min) & vc < vmin + height + r sin(-theta_v_min)
1052  // (1) & (3) theta_u_bot_min = PI - theta_u_bot_max
1053  // (2) & (4) theta_v_min = - theta_v_max
1054  float theta_u_bot_min = -7.f * M_PIf / 8.f;
1055  float theta_u_bot_max = M_PIf - theta_u_bot_min;
1056  theta_u_bot_max = vpMath::getAngleBetweenMinPiAndPi(theta_u_bot_max);
1057  float theta_v_max = -3.f * M_PIf / 8.f;
1058  float theta_v_min = -theta_v_max;
1059  float vc = OFFSET + HEIGHT + RADIUS * std::sin(theta_u_bot_min);
1060  float uc = OFFSET - RADIUS * std::cos(theta_v_min);
1061  vpImageCircle circle(vpImagePoint(vc, uc), RADIUS);
1062  float arcLengthCircle = circle.computeArcLengthInRoI(roi);
1063  float theoreticalValue = (2.f * M_PIf - ((theta_v_min - theta_v_max) + (theta_u_bot_max - theta_u_bot_min))) * RADIUS;
1064  bool isValueOK = equal(arcLengthCircle, theoreticalValue);
1065  std::string statusTest;
1066  if (isValueOK) {
1067  statusTest = "SUCCESS";
1068  }
1069  else {
1070  statusTest = "FAILED";
1071  }
1072  std::cout << "Test with intersections with the bottom and the right border, crossing each axis twice in the RoI." << std::endl;
1073  std::cout << "\tarc length =" << arcLengthCircle << std::endl;
1074  std::cout << "\ttheoretical length =" << theoreticalValue << std::endl;
1075  std::cout << "\ttest status = " << statusTest << std::endl;
1076 
1077  hasSucceeded &= isValueOK;
1078  }
1079 
1080  // Test with intersections with the top, bottom and the left border
1081  // crossing each axis twice in the RoI
1082  {
1083  // (1): u_cross_top_min = uc + r cos(theta_u_top_min) >= umin_roi ; vmin_roi = vc - r sin(theta_u_top_min)
1084  // (2): umin_roi = uc + r cos(theta_v_min); v_cross_min = vc - r sin(theta_v_min) >= vmin_roi
1085  // (3): u_cross_top_max = uc + r cos(theta_u_top_max) > umin_roi ; vmin_roi = vc - r sin(theta_u_top_max)
1086  // (4): umin_roi = uc + r cos(theta_v_max); v_cross_max = vc - r sin(theta_v_max) <= vmin_roi + height
1087  // (5): u_cross_bot_min = uc + r cos(theta_u_bottom_min) >= umin_roi ; vmin_roi + height = vc - r sin(theta_u_bottom_min)
1088  // (6): u_cross_bot_max = uc + r cos(theta_u_bottom_max) > umin_roi ; vmin_roi + height = vc - r sin(theta_u_bottom_max)
1089  // (1) & (3) theta_u_top_min = PI - theta_u_top_max
1090  // (2) & (4) theta_v_min = - theta_v_max
1091  // (5) & (6) theta_u_bottom_min = PI - theta_u_bottom_max
1092  float theta_u_top_min = 5.f * M_PIf / 8.f;
1093  float theta_u_top_max = 3.f * M_PIf / 8.f;
1094  float theta_v_min = 7.f * M_PIf / 8.f;
1095  float theta_v_max = -theta_v_min;
1096  float theta_u_bottom_min = -5.f * M_PIf / 8.f;
1097  float theta_u_bottom_max = -3.f * M_PIf / 8.f;
1098  float vc = OFFSET + HEIGHT / 2.f;
1099  float radius = -(OFFSET - vc)/ std::sin(theta_u_top_min);
1100  float uc = OFFSET - radius * std::cos(theta_v_min);
1101  vpImageCircle circle(vpImagePoint(vc, uc), radius);
1102  float arcLengthCircle = circle.computeArcLengthInRoI(roi);
1103  float theoreticalValue = ((theta_v_min - theta_u_top_min) + (theta_u_top_max - theta_u_bottom_max) + (theta_u_bottom_min - theta_v_max)) * radius;
1104  bool isValueOK = equal(arcLengthCircle, theoreticalValue);
1105  std::string statusTest;
1106  if (isValueOK) {
1107  statusTest = "SUCCESS";
1108  }
1109  else {
1110  statusTest = "FAILED";
1111  }
1112  std::cout << "Test with intersections with the top, bottom and the left border, crossing each axis twice in the RoI." << std::endl;
1113  std::cout << "\tarc length =" << arcLengthCircle << std::endl;
1114  std::cout << "\ttheoretical length =" << theoreticalValue << std::endl;
1115  std::cout << "\ttest status = " << statusTest << std::endl;
1116 
1117  hasSucceeded &= isValueOK;
1118  }
1119 
1120  // Test with intersections with the top, bottom and the left border
1121  // crossing only the top and bottom axes in the RoI
1122  {
1123  // (1): u_cross_top_min = uc + r cos(theta_u_top_min) < umin_roi ; vmin_roi = vc - r sin(theta_u_top_min)
1124  // (2): umin_roi = uc + r cos(theta_v_min); v_cross_min = vc - r sin(theta_v_min) <= vmin_roi
1125  // (3): u_cross_top_max = uc + r cos(theta_u_top_max) >= umin_roi ; vmin_roi = vc - r sin(theta_u_top_max)
1126  // (4): umin_roi = uc + r cos(theta_v_max); v_cross_max = vc - r sin(theta_v_max) >= vmin_roi + height
1127  // (5): u_cross_bot_min = uc + r cos(theta_u_bottom_min) < umin_roi ; vmin_roi + height = vc - r sin(theta_u_bottom_min)
1128  // (6): u_cross_bot_max = uc + r cos(theta_u_bottom_max) >= umin_roi ; vmin_roi + height = vc - r sin(theta_u_bottom_max)
1129  // (1) & (3) theta_u_top_min = PI - theta_u_top_max
1130  // (2) & (4) theta_v_min = - theta_v_max
1131  // (5) & (6) theta_u_bottom_min = PI - theta_u_bottom_max
1132  float theta_u_top_max = M_PIf / 6.f;
1133  float theta_u_top_min = M_PIf - theta_u_top_max;
1134  float theta_v_min = M_PIf / 3.f;
1135  float theta_u_bottom_max = -theta_u_top_max;
1136  float radius = HEIGHT;
1137  float vc = OFFSET + radius * std::sin(theta_u_top_min);
1138  float uc = OFFSET - radius * std::cos(theta_v_min);
1139  vpImageCircle circle(vpImagePoint(vc, uc), radius);
1140  float arcLengthCircle = circle.computeArcLengthInRoI(roi);
1141  float theoreticalValue = (theta_u_top_max - theta_u_bottom_max) * radius;
1142  bool isValueOK = equal(arcLengthCircle, theoreticalValue);
1143  std::string statusTest;
1144  if (isValueOK) {
1145  statusTest = "SUCCESS";
1146  }
1147  else {
1148  statusTest = "FAILED";
1149  }
1150  std::cout << "Test with intersections with the top, bottom and the left border, crossing only the top and bottom axes in the RoI." << std::endl;
1151  std::cout << "\tarc length =" << arcLengthCircle << std::endl;
1152  std::cout << "\ttheoretical length =" << theoreticalValue << std::endl;
1153  std::cout << "\ttest status = " << statusTest << std::endl;
1154 
1155  hasSucceeded &= isValueOK;
1156  }
1157 
1158  // Test with intersections with the top, bottom and the left border
1159  // crossing the top and bottom axes and touching the left axis in the RoI
1160  {
1161  // (1): u_cross_top_min = uc + r cos(theta_u_top_min) >= umin_roi ; vmin_roi = vc - r sin(theta_u_top_min)
1162  // (2): umin_roi = uc + r cos(theta_v_min); v_cross_min = vc - r sin(theta_v_min) >= vmin_roi && v_cross_min <= vmin_roi + height
1163  // (3): u_cross_top_max = uc + r cos(theta_u_top_max) >= umin_roi ; vmin_roi = vc - r sin(theta_u_top_max)
1164  // (4): umin_roi = uc + r cos(theta_v_max); v_cross_max = v_cross_min
1165  // (5): u_cross_bot_min = uc + r cos(theta_u_bottom_min) >= umin_roi ; vmin_roi + height = vc - r sin(theta_u_bottom_min)
1166  // (6): u_cross_bot_max = uc + r cos(theta_u_bottom_max) >= umin_roi ; vmin_roi + height = vc - r sin(theta_u_bottom_max)
1167  // (1) & (3) theta_u_top_min = PI - theta_u_top_max
1168  // (2) & (4) theta_v_min = - theta_v_max
1169  // (5) & (6) theta_u_bottom_min = PI - theta_u_bottom_max
1170  float theta_u_top_min = 4.f * M_PIf / 6.f;
1171  float theta_u_top_max = M_PIf - theta_u_top_min;
1172  float theta_v_min = M_PIf;
1173  float theta_u_bottom_min = -theta_u_top_min;
1174  float theta_u_bottom_max = -theta_u_top_max;
1175  float radius = HEIGHT / (2.f * std::sin(theta_u_top_min)); // vmin + h - vmin = (vc - r sin(-theta_u_top_min)) - (vc - r sin(theta_top_min))
1176  float vc = OFFSET + radius * std::sin(theta_u_top_min);
1177  float uc = OFFSET - radius * std::cos(theta_v_min);
1178  vpImageCircle circle(vpImagePoint(vc, uc), radius);
1179  float arcLengthCircle = circle.computeArcLengthInRoI(roi);
1180  float theoreticalValue = (2.f * M_PIf - ((theta_u_top_min - theta_u_top_max) + (theta_u_bottom_max - theta_u_bottom_min))) * radius;
1181  bool isValueOK = equal(arcLengthCircle, theoreticalValue);
1182  std::string statusTest;
1183  if (isValueOK) {
1184  statusTest = "SUCCESS";
1185  }
1186  else {
1187  statusTest = "FAILED";
1188  }
1189  std::cout << "Test with intersections with the top, bottom and the left border, crossing the top and bottom axes and touching the left axis in the RoI." << std::endl;
1190  std::cout << "\tarc length =" << arcLengthCircle << std::endl;
1191  std::cout << "\ttheoretical length =" << theoreticalValue << std::endl;
1192  std::cout << "\ttest status = " << statusTest << std::endl;
1193 
1194  hasSucceeded &= isValueOK;
1195  }
1196 
1197  // Test with intersections with the top, bottom and the left border
1198  // crossing only the left axis in the RoI
1199  {
1200  // (1): u_cross_top_min = uc + r cos(theta_u_top_min) < umin_roi ; vmin_roi = vc - r sin(theta_u_top_min)
1201  // (2): umin_roi = uc + r cos(theta_v_min); v_cross_min = vc - r sin(theta_v_min) >= vmin_roi
1202  // (3): u_cross_top_max = uc + r cos(theta_u_top_max) <= umin_roi ; vmin_roi = vc - r sin(theta_u_top_max)
1203  // (4): umin_roi = uc + r cos(theta_v_max); v_cross_max = vc - r sin(theta_v_max) <= vmin_roi + height
1204  // (5): u_cross_bot_min = uc + r cos(theta_u_bottom_min) < umin_roi ; vmin_roi + height = vc - r sin(theta_u_bottom_min)
1205  // (6): u_cross_bot_max = uc + r cos(theta_u_bottom_max) <= umin_roi ; vmin_roi + height = vc - r sin(theta_u_bottom_max)
1206  // (1) & (3) theta_u_top_min = PI - theta_u_top_max
1207  // (2) & (4) theta_v_min = - theta_v_max
1208  // (5) & (6) theta_u_bottom_min = PI - theta_u_bottom_max
1209  float theta_u_top_min = M_PI_2f;
1210  float theta_v_min = M_PI_4f;
1211  float theta_v_max = -theta_v_min;
1212  float radius = HEIGHT / 2.f;
1213  float vc = OFFSET + radius * std::sin(theta_u_top_min);
1214  float uc = OFFSET - radius * std::cos(theta_v_min);
1215  vpImageCircle circle(vpImagePoint(vc, uc), radius);
1216  float arcLengthCircle = circle.computeArcLengthInRoI(roi);
1217  float theoreticalValue = (theta_v_min - theta_v_max) * radius;
1218  bool isValueOK = equal(arcLengthCircle, theoreticalValue);
1219  std::string statusTest;
1220  if (isValueOK) {
1221  statusTest = "SUCCESS";
1222  }
1223  else {
1224  statusTest = "FAILED";
1225  }
1226  std::cout << "Test with intersections with the top, bottom and the left border, crossing only the left axis in the RoI." << std::endl;
1227  std::cout << "\tarc length =" << arcLengthCircle << std::endl;
1228  std::cout << "\ttheoretical length =" << theoreticalValue << std::endl;
1229  std::cout << "\ttest status = " << statusTest << std::endl;
1230 
1231  hasSucceeded &= isValueOK;
1232  }
1233 
1234  // Test with intersections with the top, bottom and the left border
1235  // crossing the left axis and touching the two others in the RoI
1236  {
1237  // (1): u_cross_top_min = uc + r cos(theta_u_top_min) >= umin_roi ; vmin_roi = vc - r sin(theta_u_top_min)
1238  // (2): umin_roi = uc + r cos(theta_v_min); v_cross_min = vc - r sin(theta_v_min) >= vmin_roi
1239  // (3): u_cross_top_max = uc + r cos(theta_u_top_max) >= umin_roi ; vmin_roi = vc - r sin(theta_u_top_max)
1240  // (4): umin_roi = uc + r cos(theta_v_max); v_cross_max = vc - r sin(theta_v_max) <= vmin_roi + height
1241  // (5): u_cross_bot_min = uc + r cos(theta_u_bottom_min) >= umin_roi ; vmin_roi + height = vc - r sin(theta_u_bottom_min)
1242  // (6): u_cross_bot_max = uc + r cos(theta_u_bottom_max) >= umin_roi ; vmin_roi + height = vc - r sin(theta_u_bottom_max)
1243  // (1) & (3) theta_u_top_min = PI - theta_u_top_max
1244  // (2) & (4) theta_v_min = - theta_v_max
1245  // (5) & (6) theta_u_bottom_min = PI - theta_u_bottom_max
1246  float theta_u_top_min = M_PI_2f;
1247  float theta_v_min = 3.f * M_PI_4f;
1248  float theta_v_max = -theta_v_min;
1249  float radius = HEIGHT / 2.f;
1250  float vc = OFFSET + radius * std::sin(theta_u_top_min);
1251  float uc = OFFSET - radius * std::cos(theta_v_min);
1252  vpImageCircle circle(vpImagePoint(vc, uc), radius);
1253  float arcLengthCircle = circle.computeArcLengthInRoI(roi);
1254  float theoreticalValue = (theta_v_min - theta_v_max) * radius;
1255  bool isValueOK = equal(arcLengthCircle, theoreticalValue);
1256  std::string statusTest;
1257  if (isValueOK) {
1258  statusTest = "SUCCESS";
1259  }
1260  else {
1261  statusTest = "FAILED";
1262  }
1263  std::cout << "Test with intersections with the top, bottom and the left border, crossing the left axis and touching the two others in the RoI." << std::endl;
1264  std::cout << "\tarc length =" << arcLengthCircle << std::endl;
1265  std::cout << "\ttheoretical length =" << theoreticalValue << std::endl;
1266  std::cout << "\ttest status = " << statusTest << std::endl;
1267 
1268  hasSucceeded &= isValueOK;
1269  }
1270 
1271  // Test with intersections with the top, bottom and the left border
1272  // crossing only the top and left axes once in the RoI
1273  {
1274  // (1): u_cross_top_min = uc + r cos(theta_u_top_min) < umin_roi ; vmin_roi = vc - r sin(theta_u_top_min)
1275  // (2): umin_roi = uc + r cos(theta_v_min); v_cross_min = vc - r sin(theta_v_min) < vmin_roi
1276  // (3): u_cross_top_max = uc + r cos(theta_u_top_max) > umin_roi ; vmin_roi = vc - r sin(theta_u_top_max)
1277  // (4): umin_roi = uc + r cos(theta_v_max); v_cross_max = vc - r sin(theta_v_max) > & && <= vmin_roi + height
1278  // (5): u_cross_bot_min = uc + r cos(theta_u_bottom_min) < umin_roi ; vmin_roi + height = vc - r sin(theta_u_bottom_min)
1279  // (6): u_cross_bot_max = uc + r cos(theta_u_bottom_max) < umin_roi ; vmin_roi + height = vc - r sin(theta_u_bottom_max)
1280  // (1) & (3) theta_u_top_min = PI - theta_u_top_max
1281  // (2) & (4) theta_v_min = - theta_v_max
1282  // (5) & (6) theta_u_bottom_min = PI - theta_u_bottom_max
1283  float theta_u_top_max = 0.f;
1284  float theta_u_bot_max = -M_PIf / 3.f;
1285  float theta_v_max = -M_PIf / 6.f;
1286  float radius = HEIGHT / (std::sin(theta_u_top_max) - std::sin(theta_u_bot_max));
1287  float uc = OFFSET - radius * std::cos(theta_v_max);
1288  float vc = OFFSET + radius * std::sin(theta_u_top_max);
1289  vpImageCircle circle(vpImagePoint(vc, uc), radius);
1290  float arcLengthCircle = circle.computeArcLengthInRoI(roi);
1291  float theoreticalValue = (theta_u_top_max - theta_v_max) * radius;
1292  bool isValueOK = equal(arcLengthCircle, theoreticalValue);
1293  std::string statusTest;
1294  if (isValueOK) {
1295  statusTest = "SUCCESS";
1296  }
1297  else {
1298  statusTest = "FAILED";
1299  }
1300  std::cout << "Test with intersections with the top, bottom and the left border, crossing only the top and left axes once in the RoI." << std::endl;
1301  std::cout << "\tarc length =" << arcLengthCircle << std::endl;
1302  std::cout << "\ttheoretical length =" << theoreticalValue << std::endl;
1303  std::cout << "\ttest status = " << statusTest << std::endl;
1304 
1305  hasSucceeded &= isValueOK;
1306  }
1307 
1308  // Test with intersections with the top, bottom and the left border
1309  // crossing the bottom and left axis once in the RoI
1310  {
1311  // (1): u_cross_top_min = uc + r cos(theta_u_top_min) <= umin_roi ; vmin_roi = vc - r sin(theta_u_top_min)
1312  // (2): umin_roi = uc + r cos(theta_v_min); v_cross_min = vc - r sin(theta_v_min) >= vmin_roi
1313  // (3): u_cross_top_max = uc + r cos(theta_u_top_max) >= umin_roi ; vmin_roi = vc - r sin(theta_u_top_max)
1314  // (4): umin_roi = uc + r cos(theta_v_max); v_cross_max = vc - r sin(theta_v_max) >= vmin_roi + height
1315  // (5): u_cross_bot_min = uc + r cos(theta_u_bottom_min) <= umin_roi ; vmin_roi + height = vc - r sin(theta_u_bottom_min)
1316  // (6): u_cross_bot_max = uc + r cos(theta_u_bottom_max) >= umin_roi ; vmin_roi + height = vc - r sin(theta_u_bottom_max)
1317  // (1) & (3) theta_u_top_min = PI - theta_u_top_max
1318  // (2) & (4) theta_v_min = - theta_v_max
1319  // (5) & (6) theta_u_bottom_min = PI - theta_u_bottom_max
1320  float theta_u_top_max = M_PIf / 3.f;
1321  float theta_u_bot_max = 0.f;
1322  float theta_v_min = M_PIf / 6.f;
1323  float radius = HEIGHT / (std::sin(theta_u_top_max) - std::sin(theta_u_bot_max));
1324  float uc = OFFSET - radius * std::cos(theta_v_min);
1325  float vc = OFFSET + radius * std::sin(theta_u_top_max);
1326  vpImageCircle circle(vpImagePoint(vc, uc), radius);
1327  float arcLengthCircle = circle.computeArcLengthInRoI(roi);
1328  float theoreticalValue = (theta_v_min - theta_u_bot_max) * radius;
1329  bool isValueOK = equal(arcLengthCircle, theoreticalValue);
1330  std::string statusTest;
1331  if (isValueOK) {
1332  statusTest = "SUCCESS";
1333  }
1334  else {
1335  statusTest = "FAILED";
1336  }
1337  std::cout << "Test with intersections with the top, bottom and the left border, crossing the bottom and left axis once in the RoI." << std::endl;
1338  std::cout << "\tarc length =" << arcLengthCircle << std::endl;
1339  std::cout << "\ttheoretical length =" << theoreticalValue << std::endl;
1340  std::cout << "\ttest status = " << statusTest << std::endl;
1341 
1342  hasSucceeded &= isValueOK;
1343  }
1344 
1345  // Test with intersections with the top, bottom and the right border
1346  // crossing each axis twice in the RoI
1347  {
1348  // (1): u_cross_top_min = uc + r cos(theta_u_top_min) < umin_roi + width ; vmin_roi = vc - r sin(theta_u_top_min)
1349  // (2): umin_roi + width = uc + r cos(theta_v_min); v_cross_min = vc - r sin(theta_v_min) >= vmin_roi
1350  // (3): u_cross_top_max = uc + r cos(theta_u_top_max) <= umin_roi + width ; vmin_roi = vc - r sin(theta_u_top_max)
1351  // (4): umin_roi + width = uc + r cos(theta_v_max); v_cross_max = vc - r sin(theta_v_max) <= vmin_roi + height
1352  // (5): u_cross_bot_min = uc + r cos(theta_u_bottom_min) < umin_roi + width ; vmin_roi + height = vc - r sin(theta_u_bottom_min)
1353  // (6): u_cross_bot_max = uc + r cos(theta_u_bottom_max) <= umin_roi + width ; vmin_roi + height = vc - r sin(theta_u_bottom_max)
1354  // (1) & (3) theta_u_top_min = PI - theta_u_top_max
1355  // (2) & (4) theta_v_min = - theta_v_max
1356  // (5) & (6) theta_u_bottom_min = PI - theta_u_bottom_max
1357  float theta_u_top_min = 5.f * M_PIf / 8.f;
1358  float theta_u_top_max = 3.f * M_PIf / 8.f;
1359  float theta_v_min = 1.f * M_PIf / 8.f;
1360  float theta_v_max = -theta_v_min;
1361  float theta_u_bottom_min = -5.f * M_PIf / 8.f;
1362  float theta_u_bottom_max = -3.f * M_PIf / 8.f;
1363  float vc = OFFSET + HEIGHT / 2.f;
1364  float radius = -(OFFSET - vc)/ std::sin(theta_u_top_min);
1365  float uc = OFFSET + WIDTH - radius * std::cos(theta_v_min);
1366  vpImageCircle circle(vpImagePoint(vc, uc), radius);
1367  float arcLengthCircle = circle.computeArcLengthInRoI(roi);
1368  float theoreticalValue = (2.f * M_PIf - ((theta_u_top_min - theta_u_top_max) + (theta_v_min - theta_v_max) + (theta_u_bottom_max - theta_u_bottom_min))) * radius;
1369  bool isValueOK = equal(arcLengthCircle, theoreticalValue);
1370  std::string statusTest;
1371  if (isValueOK) {
1372  statusTest = "SUCCESS";
1373  }
1374  else {
1375  statusTest = "FAILED";
1376  }
1377  std::cout << "Test with intersections with the top, bottom and the right border, crossing each axis twice in the RoI." << std::endl;
1378  std::cout << "\tarc length =" << arcLengthCircle << std::endl;
1379  std::cout << "\ttheoretical length =" << theoreticalValue << std::endl;
1380  std::cout << "\ttest status = " << statusTest << std::endl;
1381 
1382  hasSucceeded &= isValueOK;
1383  }
1384 
1385  // Test with intersections with the top, bottom and the right border
1386  // crossing only the top and bottom axes in the RoI
1387  {
1388  // (1): u_cross_top_min = uc + r cos(theta_u_top_min) <= umin_roi + width ; vmin_roi = vc - r sin(theta_u_top_min)
1389  // (2): umin_roi + width = uc + r cos(theta_v_min); v_cross_min = vc - r sin(theta_v_min) <= vmin_roi
1390  // (3): u_cross_top_max = uc + r cos(theta_u_top_max) > umin_roi + width ; vmin_roi = vc - r sin(theta_u_top_max)
1391  // (4): umin_roi + width = uc + r cos(theta_v_max); v_cross_max = vc - r sin(theta_v_max) >= vmin_roi + height
1392  // (5): u_cross_bot_min = uc + r cos(theta_u_bottom_min) <= umin_roi + width ; vmin_roi + height = vc - r sin(theta_u_bottom_min)
1393  // (6): u_cross_bot_max = uc + r cos(theta_u_bottom_max) > umin_roi + width ; vmin_roi + height = vc - r sin(theta_u_bottom_max)
1394  // (1) & (3) theta_u_top_min = PI - theta_u_top_max
1395  // (2) & (4) theta_v_min = - theta_v_max
1396  // (5) & (6) theta_u_bottom_min = PI - theta_u_bottom_max
1397  float theta_u_top_min = 5.f * M_PIf / 6.f;
1398  float theta_v_min = 2.f * M_PIf / 3.f;
1399  float theta_u_bottom_min = -theta_u_top_min;
1400  float radius = HEIGHT;
1401  float vc = OFFSET + radius * std::sin(theta_u_top_min);
1402  float uc = OFFSET + WIDTH - radius * std::cos(theta_v_min);
1403  vpImageCircle circle(vpImagePoint(vc, uc), radius);
1404  float arcLengthCircle = circle.computeArcLengthInRoI(roi);
1405  float theoreticalValue = (2.f * M_PIf - (theta_u_top_min - theta_u_bottom_min)) * radius;
1406  bool isValueOK = equal(arcLengthCircle, theoreticalValue);
1407  std::string statusTest;
1408  if (isValueOK) {
1409  statusTest = "SUCCESS";
1410  }
1411  else {
1412  statusTest = "FAILED";
1413  }
1414  std::cout << "Test with intersections with the top, bottom and the right border, crossing only the top and bottom axes in the RoI." << std::endl;
1415  std::cout << "\tarc length =" << arcLengthCircle << std::endl;
1416  std::cout << "\ttheoretical length =" << theoreticalValue << std::endl;
1417  std::cout << "\ttest status = " << statusTest << std::endl;
1418 
1419  hasSucceeded &= isValueOK;
1420  }
1421 
1422  // Test with intersections with the top, bottom and the right border
1423  // crossing the top and bottom axes and touching the right axis in the RoI
1424  {
1425  // (1): u_cross_top_min = uc + r cos(theta_u_top_min) < umin_roi + width ; vmin_roi = vc - r sin(theta_u_top_min)
1426  // (2): umin_roi + width = uc + r cos(theta_v_min); v_cross_min = vc - r sin(theta_v_min) >= vmin_roi && <= vmin_roi + height
1427  // (3): u_cross_top_max = uc + r cos(theta_u_top_max) <= umin_roi + width ; vmin_roi = vc - r sin(theta_u_top_max)
1428  // (4): umin_roi + width = uc + r cos(theta_v_max); v_cross_max = v_cross_min
1429  // (5): u_cross_bot_min = uc + r cos(theta_u_bottom_min) < umin_roi ; vmin_roi + height = vc - r sin(theta_u_bottom_min)
1430  // (6): u_cross_bot_max = uc + r cos(theta_u_bottom_max) <= umin_roi ; vmin_roi + height = vc - r sin(theta_u_bottom_max)
1431  // (1) & (3) theta_u_top_min = PI - theta_u_top_max
1432  // (2) & (4) theta_v_min = - theta_v_max
1433  // (5) & (6) theta_u_bottom_min = PI - theta_u_bottom_max
1434  float theta_u_top_min = 4.f * M_PIf / 6.f;
1435  float theta_u_top_max = M_PIf - theta_u_top_min;
1436  float theta_v_min = 0;
1437  float theta_u_bottom_min = -theta_u_top_min;
1438  float theta_u_bottom_max = -theta_u_top_max;
1439  float radius = HEIGHT / (2.f * std::sin(theta_u_top_min)); // vmin + h - vmin = (vc - r sin(-theta_u_top_min)) - (vc - r sin(theta_top_min))
1440  float vc = OFFSET + radius * std::sin(theta_u_top_min);
1441  float uc = OFFSET + WIDTH - radius * std::cos(theta_v_min);
1442  vpImageCircle circle(vpImagePoint(vc, uc), radius);
1443  float arcLengthCircle = circle.computeArcLengthInRoI(roi);
1444  float theoreticalValue = (2.f * M_PIf - ((theta_u_top_min - theta_u_top_max) + (theta_u_bottom_max - theta_u_bottom_min))) * radius;
1445  bool isValueOK = equal(arcLengthCircle, theoreticalValue);
1446  std::string statusTest;
1447  if (isValueOK) {
1448  statusTest = "SUCCESS";
1449  }
1450  else {
1451  statusTest = "FAILED";
1452  }
1453  std::cout << "Test with intersections with the top, bottom and the right border, crossing the top and bottom axes and touching the right axis in the RoI." << std::endl;
1454  std::cout << "\tarc length =" << arcLengthCircle << std::endl;
1455  std::cout << "\ttheoretical length =" << theoreticalValue << std::endl;
1456  std::cout << "\ttest status = " << statusTest << std::endl;
1457 
1458  hasSucceeded &= isValueOK;
1459  }
1460 
1461  // Test with intersections with the top, bottom and the right border
1462  // crossing only the right axis in the RoI
1463  {
1464  // (1): u_cross_top_min = uc + r cos(theta_u_top_min) >= umin_roi + width ; vmin_roi = vc - r sin(theta_u_top_min)
1465  // (2): umin_roi + width = uc + r cos(theta_v_min); v_cross_min = vc - r sin(theta_v_min) >= vmin_roi
1466  // (3): u_cross_top_max = uc + r cos(theta_u_top_max) > umin_roi + width ; vmin_roi = vc - r sin(theta_u_top_max)
1467  // (4): umin_roi + width = uc + r cos(theta_v_max); v_cross_max = vc - r sin(theta_v_max) <= vmin_roi + height
1468  // (5): u_cross_bot_min = uc + r cos(theta_u_bottom_min) >= umin_roi + width ; vmin_roi + height = vc - r sin(theta_u_bottom_min)
1469  // (6): u_cross_bot_max = uc + r cos(theta_u_bottom_max) > umin_roi + width ; vmin_roi + height = vc - r sin(theta_u_bottom_max)
1470  // (1) & (3) theta_u_top_min = PI - theta_u_top_max
1471  // (2) & (4) theta_v_min = - theta_v_max
1472  // (5) & (6) theta_u_bottom_min = PI - theta_u_bottom_max
1473  float theta_u_top_min = M_PI_2f;
1474  float theta_v_min = 3.f * M_PI_4f;
1475  float theta_v_max = -theta_v_min;
1476  float radius = HEIGHT / 2.f;
1477  float vc = OFFSET + radius * std::sin(theta_u_top_min);
1478  float uc = OFFSET + WIDTH - radius * std::cos(theta_v_min);
1479  vpImageCircle circle(vpImagePoint(vc, uc), radius);
1480  float arcLengthCircle = circle.computeArcLengthInRoI(roi);
1481  float theoreticalValue = (2.f * M_PIf - (theta_v_min - theta_v_max)) * radius;
1482  bool isValueOK = equal(arcLengthCircle, theoreticalValue);
1483  std::string statusTest;
1484  if (isValueOK) {
1485  statusTest = "SUCCESS";
1486  }
1487  else {
1488  statusTest = "FAILED";
1489  }
1490  std::cout << "Test with intersections with the top, bottom and the right border, crossing only the right axis in the RoI." << std::endl;
1491  std::cout << "\tarc length =" << arcLengthCircle << std::endl;
1492  std::cout << "\ttheoretical length =" << theoreticalValue << std::endl;
1493  std::cout << "\ttest status = " << statusTest << std::endl;
1494 
1495  hasSucceeded &= isValueOK;
1496  }
1497 
1498  // Test with intersections with the top, bottom and the right border
1499  // crossing the right axis and touching the two others in the RoI
1500  {
1501  // (1): u_cross_top_min = uc + r cos(theta_u_top_min) <= umin_roi + width ; vmin_roi = vc - r sin(theta_u_top_min)
1502  // (2): umin_roi + width = uc + r cos(theta_v_min); v_cross_min = vc - r sin(theta_v_min) >= vmin_roi
1503  // (3): u_cross_top_max = uc + r cos(theta_u_top_max) <= umin_roi + width ; vmin_roi = vc - r sin(theta_u_top_max)
1504  // (4): umin_roi + width = uc + r cos(theta_v_max); v_cross_max = vc - r sin(theta_v_max) <= vmin_roi + height
1505  // (5): u_cross_bot_min = uc + r cos(theta_u_bottom_min) <= umin_roi + width ; vmin_roi + height = vc - r sin(theta_u_bottom_min)
1506  // (6): u_cross_bot_max = uc + r cos(theta_u_bottom_max) <= umin_roi + width ; vmin_roi + height = vc - r sin(theta_u_bottom_max)
1507  // (1) & (3) theta_u_top_min = PI - theta_u_top_max
1508  // (2) & (4) theta_v_min = - theta_v_max
1509  // (5) & (6) theta_u_bottom_min = PI - theta_u_bottom_max
1510  float theta_u_top_min = M_PI_2f;
1511  float theta_v_min = M_PI_4f;
1512  float theta_v_max = -theta_v_min;
1513  float radius = HEIGHT / 2.f;
1514  float vc = OFFSET + radius * std::sin(theta_u_top_min);
1515  float uc = OFFSET + WIDTH - radius * std::cos(theta_v_min);
1516  vpImageCircle circle(vpImagePoint(vc, uc), radius);
1517  float arcLengthCircle = circle.computeArcLengthInRoI(roi);
1518  float theoreticalValue = (2.f * M_PIf - (theta_v_min - theta_v_max)) * radius;
1519  bool isValueOK = equal(arcLengthCircle, theoreticalValue);
1520  std::string statusTest;
1521  if (isValueOK) {
1522  statusTest = "SUCCESS";
1523  }
1524  else {
1525  statusTest = "FAILED";
1526  }
1527  std::cout << "Test with intersections with the top, bottom and the right border, crossing the right axis and touching the two others in the RoI." << std::endl;
1528  std::cout << "\tarc length =" << arcLengthCircle << std::endl;
1529  std::cout << "\ttheoretical length =" << theoreticalValue << std::endl;
1530  std::cout << "\ttest status = " << statusTest << std::endl;
1531 
1532  hasSucceeded &= isValueOK;
1533  }
1534 
1535  // Test with intersections with the top, bottom and the right border
1536  // crossing the top and right axis once in the RoI
1537  {
1538  // (1): u_cross_top_min = uc + r cos(theta_u_top_min) <= umin_roi + width ; vmin_roi = vc - r sin(theta_u_top_min)
1539  // (2): umin_roi + width = uc + r cos(theta_v_min); v_cross_min = vc - r sin(theta_v_min) <= vmin_roi
1540  // (3): u_cross_top_max = uc + r cos(theta_u_top_max) >= umin_roi + width ; vmin_roi = vc - r sin(theta_u_top_max)
1541  // (4): umin_roi + width = uc + r cos(theta_v_max); v_cross_max = vc - r sin(theta_v_max) <= vmin_roi + height
1542  // (5): u_cross_bot_min = uc + r cos(theta_u_bottom_min) >= umin_roi + width ; vmin_roi + height = vc - r sin(theta_u_bottom_min)
1543  // (6): u_cross_bot_max = uc + r cos(theta_u_bottom_max) > umin_roi + width ; vmin_roi + height = vc - r sin(theta_u_bottom_max)
1544  // (1) & (3) theta_u_top_min = PI - theta_u_top_max
1545  // (2) & (4) theta_v_min = - theta_v_max
1546  // (5) & (6) theta_u_bottom_min = PI - theta_u_bottom_max
1547  float theta_u_top_min = M_PIf;
1548  float theta_u_bot_min = -2.f * M_PIf / 3.f;
1549  float theta_v_max = -5.f * M_PIf / 6.f;
1550  float radius = HEIGHT / (std::sin(theta_u_top_min) - std::sin(theta_u_bot_min));
1551  float uc = OFFSET + WIDTH - radius * std::cos(theta_v_max);
1552  float vc = OFFSET + radius * std::sin(theta_u_top_min);
1553  vpImageCircle circle(vpImagePoint(vc, uc), radius);
1554  float arcLengthCircle = circle.computeArcLengthInRoI(roi);
1555  float theoreticalValue = (2.f * M_PIf - (theta_u_top_min - theta_v_max)) * radius;
1556  bool isValueOK = equal(arcLengthCircle, theoreticalValue);
1557  std::string statusTest;
1558  if (isValueOK) {
1559  statusTest = "SUCCESS";
1560  }
1561  else {
1562  statusTest = "FAILED";
1563  }
1564  std::cout << "Test with intersections with the top, bottom and the right border, crossing the top and right axis once in the RoI." << std::endl;
1565  std::cout << "\tarc length =" << arcLengthCircle << std::endl;
1566  std::cout << "\ttheoretical length =" << theoreticalValue << std::endl;
1567  std::cout << "\ttest status = " << statusTest << std::endl;
1568 
1569  hasSucceeded &= isValueOK;
1570  }
1571 
1572  // Test with intersections with the top, bottom and the right border
1573  // crossing the bottom and right axis once in the RoI
1574  {
1575  // (1): u_cross_top_min = uc + r cos(theta_u_top_min) >= umin_roi + width ; vmin_roi = vc - r sin(theta_u_top_min)
1576  // (2): umin_roi + width = uc + r cos(theta_v_min); v_cross_min = vc - r sin(theta_v_min) >= vmin_roi
1577  // (3): u_cross_top_max = uc + r cos(theta_u_top_max) >= umin_roi + width ; vmin_roi = vc - r sin(theta_u_top_max)
1578  // (4): umin_roi + width = uc + r cos(theta_v_max); v_cross_max = vc - r sin(theta_v_max) >= vmin_roi + height
1579  // (5): u_cross_bot_min = uc + r cos(theta_u_bottom_min) <= umin_roi + width ; vmin_roi + height = vc - r sin(theta_u_bottom_min)
1580  // (6): u_cross_bot_max = uc + r cos(theta_u_bottom_max) >= umin_roi + width ; vmin_roi + height = vc - r sin(theta_u_bottom_max)
1581  // (1) & (3) theta_u_top_min = PI - theta_u_top_max
1582  // (2) & (4) theta_v_min = - theta_v_max
1583  // (5) & (6) theta_u_bottom_min = PI - theta_u_bottom_max
1584  float theta_u_top_min = 2.f * M_PIf / 3.f;
1585  float theta_u_bot_min = M_PIf;
1586  float theta_v_min = 5.f * M_PIf / 6.f;
1587  float radius = HEIGHT / (std::sin(theta_u_top_min) - std::sin(theta_u_bot_min));
1588  float uc = OFFSET + WIDTH - radius * std::cos(theta_v_min);
1589  float vc = OFFSET + radius * std::sin(theta_u_top_min);
1590  vpImageCircle circle(vpImagePoint(vc, uc), radius);
1591  float arcLengthCircle = circle.computeArcLengthInRoI(roi);
1592  float theoreticalValue = (theta_u_bot_min - theta_v_min) * radius;
1593  bool isValueOK = equal(arcLengthCircle, theoreticalValue);
1594  std::string statusTest;
1595  if (isValueOK) {
1596  statusTest = "SUCCESS";
1597  }
1598  else {
1599  statusTest = "FAILED";
1600  }
1601  std::cout << "Test with intersections with the top, bottom and the right border, crossing the bottom and right axis once in the RoI." << std::endl;
1602  std::cout << "\tarc length =" << arcLengthCircle << std::endl;
1603  std::cout << "\ttheoretical length =" << theoreticalValue << std::endl;
1604  std::cout << "\ttest status = " << statusTest << std::endl;
1605 
1606  hasSucceeded &= isValueOK;
1607  }
1608 
1609  // Test with intersections with the top, left and the right border
1610  // crossing each axis twice
1611  {
1612  // (1): u_cross_top_min = uc + r cos(theta_u_top_min) >= umin_roi ; vmin_roi = vc - r sin(theta_u_top_min)
1613  // (2): umin_roi = uc + r cos(theta_v_left_min); v_cross_left_min = vc - r sin(theta_v_left_min) >= vmin_roi
1614  // (3): u_cross_top_max = uc + r cos(theta_u_top_max) <= umin_roi + width ; vmin_roi = vc - r sin(theta_u_top_max)
1615  // (4): umin_roi = uc + r cos(theta_v_left_max); v_cross_left_max = vc - r sin(theta_v_left_max) <= vmin_roi + height
1616  // (5): umin_roi + width = uc + r cos(theta_v_right_min) ; v_cross_right_min = vc - r sin(theta_v_right_min)
1617  // (6): umin_roi + width = uc + r cos(theta_v_right_max) ; v_cross_right_max = vc - r sin(theta_v_right_max)
1618  // (5) - (2) width = r (cos(theta_v_right_min) - cos(theta_v_left_min))
1619  // (1) & (3) theta_u_top_min = PI - theta_u_top_max
1620  // (2) & (4) theta_v_left_min = - theta_v_left_max
1621  // (5) & (6) theta_v_right_min = - theta_v_right_max
1622 
1623  float theta_v_left_min = 7.f * M_PIf / 8.f;
1624  float theta_v_left_max = -theta_v_left_min;
1625  float theta_v_right_min = M_PIf / 8.f;
1626  float theta_v_right_max = -theta_v_right_min;
1627  float theta_u_top_min = 5.f * M_PIf / 8.f;
1628  float theta_u_top_max = M_PIf - theta_u_top_min;
1629  float radius = WIDTH_SWITCHED / (std::cos(theta_v_right_min) - std::cos(theta_v_left_min));
1630  float uc = OFFSET + WIDTH_SWITCHED - radius * std::cos(theta_v_right_min);
1631  float vc = OFFSET + radius * std::sin(theta_u_top_min);
1632  vpImageCircle circle(vpImagePoint(vc, uc), radius);
1633  float arcLengthCircle = circle.computeArcLengthInRoI(switchedRoI);
1634  float theoreticalValue = ((theta_v_left_min - theta_u_top_min) + (theta_u_top_max - theta_v_right_min) + (theta_v_right_max - theta_v_left_max)) * radius;
1635  bool isValueOK = equal(arcLengthCircle, theoreticalValue);
1636  std::string statusTest;
1637  if (isValueOK) {
1638  statusTest = "SUCCESS";
1639  }
1640  else {
1641  statusTest = "FAILED";
1642  }
1643  std::cout << "Test with intersections with the top, left and the right border, crossing each axis twice in the RoI." << std::endl;
1644  std::cout << "\tarc length =" << arcLengthCircle << std::endl;
1645  std::cout << "\ttheoretical length =" << theoreticalValue << std::endl;
1646  std::cout << "\ttest status = " << statusTest << std::endl;
1647 
1648  hasSucceeded &= isValueOK;
1649  }
1650 
1651  // Test with intersections with the top, left and the right border
1652  // crossing only the top axis
1653  {
1654  // (1): u_cross_top_min = uc + r cos(theta_u_top_min) >= umin_roi ; vmin_roi = vc - r sin(theta_u_top_min)
1655  // (2): umin_roi = uc + r cos(theta_v_left_min); v_cross_left_min = vc - r sin(theta_v_left_min) < vmin_roi
1656  // (3): u_cross_top_max = uc + r cos(theta_u_top_max) <= umin_roi + width ; vmin_roi = vc - r sin(theta_u_top_max)
1657  // (4): umin_roi = uc + r cos(theta_v_left_max); v_cross_left_max = vc - r sin(theta_v_left_max) <= vmin_roi
1658  // (5): umin_roi + width = uc + r cos(theta_v_right_min) ; v_cross_right_min = vc - r sin(theta_v_right_min) < vmin_roi
1659  // (6): umin_roi + width = uc + r cos(theta_v_right_max) ; v_cross_right_max = vc - r sin(theta_v_right_max) <= vmin_roi
1660  // (1) & (3) theta_u_top_min = PI - theta_u_top_max
1661  // (2) & (4) theta_v_left_min = - theta_v_left_max
1662  // (5) & (6) theta_v_right_min = - theta_v_right_max
1663 
1664  float theta_u_top_min = -2.f * M_PIf / 3.f;
1665  float uc = OFFSET + WIDTH_SWITCHED/2.f;
1666  float vc = OFFSET + RADIUS * std::sin(theta_u_top_min);
1667  vpImageCircle circle(vpImagePoint(vc, uc), RADIUS);
1668  float arcLengthCircle = circle.computeArcLengthInRoI(switchedRoI);
1669  float theoreticalValue = (M_PIf/3.f) * RADIUS;
1670  bool isValueOK = equal(arcLengthCircle, theoreticalValue);
1671  std::string statusTest;
1672  if (isValueOK) {
1673  statusTest = "SUCCESS";
1674  }
1675  else {
1676  statusTest = "FAILED";
1677  }
1678  std::cout << "Test with intersections with the top, left and the right border, crossing only the top axis." << std::endl;
1679  std::cout << "\tarc length =" << arcLengthCircle << std::endl;
1680  std::cout << "\ttheoretical length =" << theoreticalValue << std::endl;
1681  std::cout << "\ttest status = " << statusTest << std::endl;
1682 
1683  hasSucceeded &= isValueOK;
1684  }
1685 
1686  // Test with intersections with the top, left and the right border
1687  // crossing left right only
1688  {
1689  // (1): u_cross_top_min = uc + r cos(theta_u_top_min) <= umin_roi ; vmin_roi = vc - r sin(theta_u_top_min)
1690  // (2): umin_roi = uc + r cos(theta_v_left_min); v_cross_left_min = vc - r sin(theta_v_left_min) < vmin_roi
1691  // (3): u_cross_top_max = uc + r cos(theta_u_top_max) >= umin_roi + width ; vmin_roi = vc - r sin(theta_u_top_max)
1692  // (4): umin_roi = uc + r cos(theta_v_left_max); v_cross_left_max = vc - r sin(theta_v_left_max) <= vmin_roi + height
1693  // (5): umin_roi + width = uc + r cos(theta_v_right_min) ; v_cross_right_min = vc - r sin(theta_v_right_min) < vmin_roi
1694  // (6): umin_roi + width = uc + r cos(theta_v_right_max) ; v_cross_right_max = vc - r sin(theta_v_right_max) <= vmin_roi + height
1695  // (6) - (3) width = r (cos(theta_v_right_max) - cos(theta_v_left_max))
1696  // (1) & (3) theta_u_top_min = PI - theta_u_top_max
1697  // (2) & (4) theta_v_left_min = - theta_v_left_max
1698  // (5) & (6) theta_v_right_min = - theta_v_right_max
1699 
1700  float theta_v_left_max = -5.f * M_PIf / 8.f;
1701  float theta_v_right_max = -3.f *M_PIf / 8.f;
1702  float theta_u_top_min = -7.f * M_PIf / 8.f;
1703  float radius = WIDTH_SWITCHED / (std::cos(theta_v_right_max) - std::cos(theta_v_left_max));
1704  float uc = OFFSET - radius * std::cos(theta_v_left_max);
1705  float vc = OFFSET + radius * std::sin(theta_u_top_min);
1706  vpImageCircle circle(vpImagePoint(vc, uc), radius);
1707  float arcLengthCircle = circle.computeArcLengthInRoI(switchedRoI);
1708  float theoreticalValue = (theta_v_right_max - theta_v_left_max) * radius;
1709  bool isValueOK = equal(arcLengthCircle, theoreticalValue);
1710  std::string statusTest;
1711  if (isValueOK) {
1712  statusTest = "SUCCESS";
1713  }
1714  else {
1715  statusTest = "FAILED";
1716  }
1717  std::cout << "Test with intersections with the top, left and the right border, crossing only left right in the RoI." << std::endl;
1718  std::cout << "\tarc length =" << arcLengthCircle << std::endl;
1719  std::cout << "\ttheoretical length =" << theoreticalValue << std::endl;
1720  std::cout << "\ttest status = " << statusTest << std::endl;
1721 
1722  hasSucceeded &= isValueOK;
1723  }
1724 
1725  // Test with intersections with the top, left and the right border
1726  // crossing only the top and left axes
1727  {
1728  // (1): u_cross_top_min = uc + r cos(theta_u_top_min) < umin_roi ; vmin_roi = vc - r sin(theta_u_top_min)
1729  // (2): umin_roi = uc + r cos(theta_v_left_min); v_cross_left_min = vc - r sin(theta_v_left_min) < vmin_roi
1730  // (3): u_cross_top_max = uc + r cos(theta_u_top_max) >= umin_roi ; vmin_roi = vc - r sin(theta_u_top_max)
1731  // (4): umin_roi = uc + r cos(theta_v_left_max); v_cross_left_max = vc - r sin(theta_v_left_max) >= vmin_roi
1732  // (5): umin_roi + width = uc + r cos(theta_v_right_min) ; v_cross_right_min = vc - r sin(theta_v_right_min) < vmin_roi
1733  // (6): umin_roi + width = uc + r cos(theta_v_right_max) ; v_cross_right_max = vc - r sin(theta_v_right_max) <= vmin_roi
1734  // (6) - (4) => width = r (cos(theta_v_right_max) - cos(theta_v_left_max))
1735  // (1) & (3) theta_u_top_min = PI - theta_u_top_max
1736  // (2) & (4) theta_v_left_min = - theta_v_left_max
1737  // (5) & (6) theta_v_right_min = - theta_v_right_max
1738 
1739  float theta_u_top_max = -M_PIf / 3.f;
1740  float theta_v_right_max = 0.f;
1741  float theta_v_left_max = -M_PI_2f;
1742  float radius = WIDTH_SWITCHED / (std::cos(theta_v_right_max) - std::cos(theta_v_left_max));
1743  float uc = OFFSET;
1744  float vc = OFFSET + radius * std::sin(theta_u_top_max);
1745  vpImageCircle circle(vpImagePoint(vc, uc), radius);
1746  float arcLengthCircle = circle.computeArcLengthInRoI(switchedRoI);
1747  float theoreticalValue = (theta_u_top_max - theta_v_left_max) * radius;
1748  bool isValueOK = equal(arcLengthCircle, theoreticalValue);
1749  std::string statusTest;
1750  if (isValueOK) {
1751  statusTest = "SUCCESS";
1752  }
1753  else {
1754  statusTest = "FAILED";
1755  }
1756  std::cout << "Test with intersections with the top, left and the right border, crossing only the top and left axes." << std::endl;
1757  std::cout << "\tarc length =" << arcLengthCircle << std::endl;
1758  std::cout << "\ttheoretical length =" << theoreticalValue << std::endl;
1759  std::cout << "\ttest status = " << statusTest << std::endl;
1760 
1761  hasSucceeded &= isValueOK;
1762  }
1763 
1764  // Test with intersections with the top, left and the right border
1765  // crossing only the top and right axes
1766  {
1767  // (1): u_cross_top_min = uc + r cos(theta_u_top_min) < umin_roi + width ; vmin_roi = vc - r sin(theta_u_top_min)
1768  // (2): umin_roi = uc + r cos(theta_v_left_min); v_cross_left_min = vc - r sin(theta_v_left_min) < vmin_roi
1769  // (3): u_cross_top_max = uc + r cos(theta_u_top_max) >= umin_roi + width ; vmin_roi = vc - r sin(theta_u_top_max)
1770  // (4): umin_roi = uc + r cos(theta_v_left_max); v_cross_left_max = vc - r sin(theta_v_left_max) < vmin_roi
1771  // (5): umin_roi + width = uc + r cos(theta_v_right_min) ; v_cross_right_min = vc - r sin(theta_v_right_min) < vmin_roi
1772  // (6): umin_roi + width = uc + r cos(theta_v_right_max) ; v_cross_right_max = vc - r sin(theta_v_right_max) >= vmin_roi
1773  // (6) - (4) => width = r (cos(theta_v_right_max) - cos(theta_v_left_max))
1774  // (1) & (3) theta_u_top_min = PI - theta_u_top_max
1775  // (2) & (4) theta_v_left_min = - theta_v_left_max
1776  // (5) & (6) theta_v_right_min = - theta_v_right_max
1777 
1778  float theta_u_top_min = -2.f * M_PIf / 3.f;
1779  float theta_v_left_max = M_PIf;
1780  float theta_v_right_max = -M_PI_2f;
1781  float radius = WIDTH_SWITCHED / (std::cos(theta_v_right_max) - std::cos(theta_v_left_max));
1782  float uc = OFFSET + WIDTH_SWITCHED;
1783  float vc = OFFSET + radius * std::sin(theta_u_top_min);
1784  vpImageCircle circle(vpImagePoint(vc, uc), radius);
1785  float arcLengthCircle = circle.computeArcLengthInRoI(switchedRoI);
1786  float theoreticalValue = (theta_v_right_max - theta_u_top_min) * radius;
1787  bool isValueOK = equal(arcLengthCircle, theoreticalValue);
1788  std::string statusTest;
1789  if (isValueOK) {
1790  statusTest = "SUCCESS";
1791  }
1792  else {
1793  statusTest = "FAILED";
1794  }
1795  std::cout << "Test with intersections with the top, left and the right border, crossing only the top and right axes." << std::endl;
1796  std::cout << "\tarc length =" << arcLengthCircle << std::endl;
1797  std::cout << "\ttheoretical length =" << theoreticalValue << std::endl;
1798  std::cout << "\ttest status = " << statusTest << std::endl;
1799 
1800  hasSucceeded &= isValueOK;
1801  }
1802 
1803  // Test with intersections with the bottom, left and the right border
1804  // crossing each axis twice
1805  {
1806  // (1): u_cross_bot_min = uc + r cos(theta_u_top_min) >= umin_roi ; vmin_roi + height = vc - r sin(theta_u_top_min)
1807  // (2): umin_roi = uc + r cos(theta_v_left_min); v_cross_left_min = vc - r sin(theta_v_left_min) >= vmin_roi
1808  // (3): u_cross_bot_max = uc + r cos(theta_u_top_max) <= umin_roi + width ; vmin_roi + height = vc - r sin(theta_u_top_max)
1809  // (4): umin_roi = uc + r cos(theta_v_left_max); v_cross_left_max = vc - r sin(theta_v_left_max) <= vmin_roi + height
1810  // (5): umin_roi + width = uc + r cos(theta_v_right_min) ; v_cross_right_min = vc - r sin(theta_v_right_min)
1811  // (6): umin_roi + width = uc + r cos(theta_v_right_max) ; v_cross_right_max = vc - r sin(theta_v_right_max)
1812  // (5) - (2) width = r (cos(theta_v_right_min) - cos(theta_v_left_min))
1813  // (1) & (3) theta_u_top_min = PI - theta_u_top_max
1814  // (2) & (4) theta_v_left_min = - theta_v_left_max
1815  // (5) & (6) theta_v_right_min = - theta_v_right_max
1816 
1817  float theta_v_left_min = 7.f * M_PIf / 8.f;
1818  float theta_v_left_max = -theta_v_left_min;
1819  float theta_v_right_min = M_PIf / 8.f;
1820  float theta_v_right_max = -theta_v_right_min;
1821  float theta_u_bot_min = -5.f * M_PIf / 8.f;
1822  float theta_u_bot_max = -M_PIf - theta_u_bot_min;
1823  float radius = WIDTH_SWITCHED / (std::cos(theta_v_right_min) - std::cos(theta_v_left_min));
1824  float uc = OFFSET + WIDTH_SWITCHED - radius * std::cos(theta_v_right_min);
1825  float vc = OFFSET + HEIGHT_SWITCHED + radius * std::sin(theta_u_bot_min);
1826  vpImageCircle circle(vpImagePoint(vc, uc), radius);
1827  float arcLengthCircle = circle.computeArcLengthInRoI(switchedRoI);
1828  float theoreticalValue = ((theta_v_left_min - theta_v_right_min) + (theta_v_right_max - theta_u_bot_max) + (theta_u_bot_min - theta_v_left_max)) * radius;
1829  bool isValueOK = equal(arcLengthCircle, theoreticalValue);
1830  std::string statusTest;
1831  if (isValueOK) {
1832  statusTest = "SUCCESS";
1833  }
1834  else {
1835  statusTest = "FAILED";
1836  }
1837  std::cout << "Test with intersections with the bottom, left and the right border, crossing each axis twice in the RoI." << std::endl;
1838  std::cout << "\tarc length =" << arcLengthCircle << std::endl;
1839  std::cout << "\ttheoretical length =" << theoreticalValue << std::endl;
1840  std::cout << "\ttest status = " << statusTest << std::endl;
1841 
1842  hasSucceeded &= isValueOK;
1843  }
1844 
1845  // Test with intersections with the bottom, left and the right border
1846  // crossing only the bottom one in the RoI
1847  {
1848  // (1): u_cross_bot_min = uc + r cos(theta_u_top_min) >= umin_roi ; vmin_roi + height = vc - r sin(theta_u_top_min)
1849  // (2): umin_roi = uc + r cos(theta_v_left_min); v_cross_left_min = vc - r sin(theta_v_left_min) >= vmin_roi + height
1850  // (3): u_cross_bot_max = uc + r cos(theta_u_top_max) <= umin_roi + width ; vmin_roi + height = vc - r sin(theta_u_top_max)
1851  // (4): umin_roi = uc + r cos(theta_v_left_max); v_cross_left_max = vc - r sin(theta_v_left_max) >= vmin_roi + height
1852  // (5): umin_roi + width = uc + r cos(theta_v_right_min) ; v_cross_right_min = vc - r sin(theta_v_right_min) >= vmin_roi + height
1853  // (6): umin_roi + width = uc + r cos(theta_v_right_max) ; v_cross_right_max = vc - r sin(theta_v_right_max) >= vmin_roi + height
1854  // (5) - (2) width = r (cos(theta_v_right_min) - cos(theta_v_left_min))
1855  // (1) & (3) theta_u_top_min = PI - theta_u_top_max
1856  // (2) & (4) theta_v_left_min = - theta_v_left_max
1857  // (5) & (6) theta_v_right_min = - theta_v_right_max
1858  float theta_u_bot_min = 2.f * M_PIf / 3.f;
1859  float theta_u_bot_max = M_PIf - theta_u_bot_min;
1860  float theta_v_left_min = 5.f * M_PIf / 6.f;
1861  float theta_v_right_min = M_PIf / 6.f;
1862  float radius = WIDTH_SWITCHED / (std::cos(theta_v_right_min) - std::cos(theta_v_left_min));
1863  float uc = OFFSET + WIDTH_SWITCHED - radius * std::cos(theta_v_right_min);
1864  float vc = OFFSET + HEIGHT_SWITCHED + radius * std::sin(theta_u_bot_min);
1865  vpImageCircle circle(vpImagePoint(vc, uc), radius);
1866  float arcLengthCircle = circle.computeArcLengthInRoI(switchedRoI);
1867  float theoreticalValue = ((theta_u_bot_min - theta_u_bot_max)) * radius;
1868  bool isValueOK = equal(arcLengthCircle, theoreticalValue);
1869  std::string statusTest;
1870  if (isValueOK) {
1871  statusTest = "SUCCESS";
1872  }
1873  else {
1874  statusTest = "FAILED";
1875  }
1876  std::cout << "Test with intersections with the bottom, left and the right border, crossing only the bottom one in the RoI." << std::endl;
1877  std::cout << "\tarc length =" << arcLengthCircle << std::endl;
1878  std::cout << "\ttheoretical length =" << theoreticalValue << std::endl;
1879  std::cout << "\ttest status = " << statusTest << std::endl;
1880 
1881  hasSucceeded &= isValueOK;
1882  }
1883 
1884  // Test with intersections with the bottom, left and the right border
1885  // crossing only the left and right in the RoI
1886  {
1887  // (1): u_cross_bot_min = uc + r cos(theta_u_top_min) <= umin_roi ; vmin_roi + height = vc - r sin(theta_u_top_min)
1888  // (2): umin_roi = uc + r cos(theta_v_left_min); v_cross_left_min = vc - r sin(theta_v_left_min) <= vmin_roi + height
1889  // (3): u_cross_bot_max = uc + r cos(theta_u_top_max) >= umin_roi + width ; vmin_roi + height = vc - r sin(theta_u_top_max)
1890  // (4): umin_roi = uc + r cos(theta_v_left_max); v_cross_left_max = vc - r sin(theta_v_left_max) <= vmin_roi + height
1891  // (5): umin_roi + width = uc + r cos(theta_v_right_min) ; v_cross_right_min = vc - r sin(theta_v_right_min) >= vmin_roi + height
1892  // (6): umin_roi + width = uc + r cos(theta_v_right_max) ; v_cross_right_max = vc - r sin(theta_v_right_max) >= vmin_roi + height
1893  // (5) - (2) width = r (cos(theta_v_right_min) - cos(theta_v_left_min))
1894  // (1) & (3) theta_u_top_min = PI - theta_u_top_max
1895  // (2) & (4) theta_v_left_min = - theta_v_left_max
1896  // (5) & (6) theta_v_right_min = - theta_v_right_max
1897  float theta_u_bot_min = 7.f * M_PIf / 8.f;
1898  float theta_v_left_min = 5.f * M_PIf / 8.f;
1899  float theta_v_right_min = 3.f * M_PIf / 8.f;
1900  float radius = WIDTH_SWITCHED / (std::cos(theta_v_right_min) - std::cos(theta_v_left_min));
1901  float uc = OFFSET + WIDTH_SWITCHED - radius * std::cos(theta_v_right_min);
1902  float vc = OFFSET + HEIGHT_SWITCHED + radius * std::sin(theta_u_bot_min);
1903  vpImageCircle circle(vpImagePoint(vc, uc), radius);
1904  float arcLengthCircle = circle.computeArcLengthInRoI(switchedRoI);
1905  float theoreticalValue = ((theta_v_left_min - theta_v_right_min)) * radius;
1906  bool isValueOK = equal(arcLengthCircle, theoreticalValue);
1907  std::string statusTest;
1908  if (isValueOK) {
1909  statusTest = "SUCCESS";
1910  }
1911  else {
1912  statusTest = "FAILED";
1913  }
1914  std::cout << "Test with intersections with the bottom, left and the right border, crossing only the left and right in the RoI." << std::endl;
1915  std::cout << "\tarc length =" << arcLengthCircle << std::endl;
1916  std::cout << "\ttheoretical length =" << theoreticalValue << std::endl;
1917  std::cout << "\ttest status = " << statusTest << std::endl;
1918 
1919  hasSucceeded &= isValueOK;
1920  }
1921 
1922  // Test with intersections with the bottom, left and the right border
1923  // crossing only the left and bottom in the RoI
1924  {
1925  // (1): u_cross_bot_min = uc + r cos(theta_u_top_min) <= umin_roi ; vmin_roi + height = vc - r sin(theta_u_top_min)
1926  // (2): umin_roi = uc + r cos(theta_v_left_min); v_cross_left_min = vc - r sin(theta_v_left_min) <= vmin_roi + height
1927  // (3): u_cross_bot_max = uc + r cos(theta_u_top_max) <= umin_roi + width ; vmin_roi + height = vc - r sin(theta_u_top_max)
1928  // (4): umin_roi = uc + r cos(theta_v_left_max); v_cross_left_max = vc - r sin(theta_v_left_max) >= vmin_roi + height
1929  // (5): umin_roi + width = uc + r cos(theta_v_right_min) ; v_cross_right_min = vc - r sin(theta_v_right_min) >= vmin_roi + height
1930  // (6): umin_roi + width = uc + r cos(theta_v_right_max) ; v_cross_right_max = vc - r sin(theta_v_right_max) >= vmin_roi + height
1931  // (5) - (2) width = r (cos(theta_v_right_min) - cos(theta_v_left_min))
1932  // (1) & (3) theta_u_top_min = PI - theta_u_top_max
1933  // (2) & (4) theta_v_left_min = - theta_v_left_max
1934  // (5) & (6) theta_v_right_min = - theta_v_right_max
1935  float theta_u_bot_max = M_PIf / 3.f;
1936  float theta_v_left_min = M_PI_2f;
1937  float theta_v_right_min = 0.f;
1938  float radius = WIDTH_SWITCHED / (std::cos(theta_v_right_min) - std::cos(theta_v_left_min));
1939  float uc = OFFSET;
1940  float vc = OFFSET + HEIGHT_SWITCHED + radius * std::sin(theta_u_bot_max);
1941  vpImageCircle circle(vpImagePoint(vc, uc), radius);
1942  float arcLengthCircle = circle.computeArcLengthInRoI(switchedRoI);
1943  float theoreticalValue = ((theta_v_left_min - theta_u_bot_max)) * radius;
1944  bool isValueOK = equal(arcLengthCircle, theoreticalValue);
1945  std::string statusTest;
1946  if (isValueOK) {
1947  statusTest = "SUCCESS";
1948  }
1949  else {
1950  statusTest = "FAILED";
1951  }
1952  std::cout << "Test with intersections with the bottom, left and the right border, crossing only the left and bottom in the RoI." << std::endl;
1953  std::cout << "\tarc length =" << arcLengthCircle << std::endl;
1954  std::cout << "\ttheoretical length =" << theoreticalValue << std::endl;
1955  std::cout << "\ttest status = " << statusTest << std::endl;
1956 
1957  hasSucceeded &= isValueOK;
1958  }
1959 
1960  // Test with intersections with the bottom, left and the right border
1961  // crossing only the right and bottom in the RoI
1962  {
1963  // (1): u_cross_bot_min = uc + r cos(theta_u_top_min) <= umin_roi + width ; vmin_roi + height = vc - r sin(theta_u_top_min)
1964  // (2): umin_roi = uc + r cos(theta_v_left_min); v_cross_left_min = vc - r sin(theta_v_left_min) >= vmin_roi + height
1965  // (3): u_cross_bot_max = uc + r cos(theta_u_top_max) >= umin_roi + width ; vmin_roi + height = vc - r sin(theta_u_top_max)
1966  // (4): umin_roi = uc + r cos(theta_v_left_max); v_cross_left_max = vc - r sin(theta_v_left_max) >= vmin_roi + height
1967  // (5): umin_roi + width = uc + r cos(theta_v_right_min) ; v_cross_right_min = vc - r sin(theta_v_right_min) <= vmin_roi + height
1968  // (6): umin_roi + width = uc + r cos(theta_v_right_max) ; v_cross_right_max = vc - r sin(theta_v_right_max) >= vmin_roi + height
1969  // (5) - (2) width = r (cos(theta_v_right_min) - cos(theta_v_left_min))
1970  // (1) & (3) theta_u_top_min = PI - theta_u_top_max
1971  // (2) & (4) theta_v_left_min = - theta_v_left_max
1972  // (5) & (6) theta_v_right_min = - theta_v_right_max
1973  float theta_u_bot_min = 2.f * M_PIf / 3.f;
1974  float theta_v_right_min = M_PI_2f;
1975  float theta_v_left_min = M_PIf;
1976  float radius = WIDTH_SWITCHED / (std::cos(theta_v_right_min) - std::cos(theta_v_left_min));
1977  float uc = OFFSET + WIDTH_SWITCHED;
1978  float vc = OFFSET + HEIGHT_SWITCHED + radius * std::sin(theta_u_bot_min);
1979  vpImageCircle circle(vpImagePoint(vc, uc), radius);
1980  float arcLengthCircle = circle.computeArcLengthInRoI(switchedRoI);
1981  float theoreticalValue = ((theta_u_bot_min - theta_v_right_min)) * radius;
1982  bool isValueOK = equal(arcLengthCircle, theoreticalValue);
1983  std::string statusTest;
1984  if (isValueOK) {
1985  statusTest = "SUCCESS";
1986  }
1987  else {
1988  statusTest = "FAILED";
1989  }
1990  std::cout << "Test with intersections with the bottom, left and the right border, crossing only the right and bottom in the RoI." << std::endl;
1991  std::cout << "\tarc length =" << arcLengthCircle << std::endl;
1992  std::cout << "\ttheoretical length =" << theoreticalValue << std::endl;
1993  std::cout << "\ttest status = " << statusTest << std::endl;
1994 
1995  hasSucceeded &= isValueOK;
1996  }
1997 
1998  // Test with intersections with the top and bottom only,
1999  // crossing each axis twice in the RoI
2000  {
2001  // (1): u_cross_top_min = uc + r cos(theta_u_top_min) < umin_roi + width ; vmin_roi = vc - r sin(theta_u_top_min)
2002  // (3): u_cross_top_max = uc + r cos(theta_u_top_max) <= umin_roi + width ; vmin_roi = vc - r sin(theta_u_top_max)
2003  // (5): u_cross_bot_min = uc + r cos(theta_u_bottom_min) < umin_roi + width ; vmin_roi + height = vc - r sin(theta_u_bottom_min)
2004  // (6): u_cross_bot_max = uc + r cos(theta_u_bottom_max) <= umin_roi + width ; vmin_roi + height = vc - r sin(theta_u_bottom_max)
2005  // (1) & (3) theta_u_top_min = PI - theta_u_top_max
2006  // (5) & (6) theta_u_bottom_min = PI - theta_u_bottom_max
2007  float theta_u_top_min = 2.f * M_PIf / 3.f;
2008  float theta_u_top_max = M_PIf / 3.f;
2009  float theta_u_bottom_min = -2.f * M_PIf / 3.f;
2010  float theta_u_bottom_max = -M_PIf / 3.f;
2011  float uc = OFFSET + WIDTH / 2.f;
2012  float vc = OFFSET + HEIGHT / 2.f;
2013  float radius = -(OFFSET - vc)/ std::sin(theta_u_top_min);
2014 
2015  vpImageCircle circle(vpImagePoint(vc, uc), radius);
2016  float arcLengthCircle = circle.computeArcLengthInRoI(roi);
2017  float theoreticalValue = (2.f * M_PIf - ((theta_u_top_min - theta_u_top_max) + (theta_u_bottom_max - theta_u_bottom_min))) * radius;
2018  bool isValueOK = equal(arcLengthCircle, theoreticalValue);
2019  std::string statusTest;
2020  if (isValueOK) {
2021  statusTest = "SUCCESS";
2022  }
2023  else {
2024  statusTest = "FAILED";
2025  }
2026  std::cout << "Test with intersections with the top and bottom borders only, crossing each axis twice in the RoI." << std::endl;
2027  std::cout << "\tarc length =" << arcLengthCircle << std::endl;
2028  std::cout << "\ttheoretical length =" << theoreticalValue << std::endl;
2029  std::cout << "\ttest status = " << statusTest << std::endl;
2030 
2031  hasSucceeded &= isValueOK;
2032  }
2033 
2034  // Test with intersections with the right and left only,
2035  // crossing each axis twice in the RoI
2036  {
2037  // (2): u_min = uc + r cos(theta_v_left_min) ; v_cross_left_min = vc - r sin(theta_v_left_min) > vmin_roi
2038  // (4): u_min = uc + r cos(theta_v_left_max) ; v_cross_left_max = vc - r sin(theta_v_left_max) < vmax_roi
2039  // (5): u_min + width = uc + r cos(theta_v_right_min); v_cross_right_min = vc - r sin(theta_v_right_min)
2040  // (6): u_min + width = uc + r cos(theta_v_right_max); v_cross_right_max = vc - r sin(theta_v_right_max)
2041  // (2) & (4) theta_v_left_min = - theta_v_left_max
2042  // (5) & (6) theta_v_right_min = - theta_v_right_max
2043  float theta_v_left_min = 5.f * M_PIf / 6.f;
2044  float theta_v_left_max = -theta_v_left_min;
2045  float theta_v_right_min = M_PIf / 6.f;
2046  float theta_v_right_max = -theta_v_right_min;
2047  float uc = OFFSET + HEIGHT / 2.f;
2048  float vc = OFFSET + WIDTH / 2.f;
2049  float radius = (OFFSET - uc)/ std::cos(theta_v_left_min);
2050 
2051  vpImageCircle circle(vpImagePoint(vc, uc), radius);
2052  float arcLengthCircle = circle.computeArcLengthInRoI(switchedRoI);
2053  float theoreticalValue = ((theta_v_left_min - theta_v_right_min) + (theta_v_right_max - theta_v_left_max)) * radius;
2054  bool isValueOK = equal(arcLengthCircle, theoreticalValue);
2055  std::string statusTest;
2056  if (isValueOK) {
2057  statusTest = "SUCCESS";
2058  }
2059  else {
2060  statusTest = "FAILED";
2061  }
2062  std::cout << "Test with intersections with the right and left borders only, crossing each axis twice in the RoI." << std::endl;
2063  std::cout << "\tarc length =" << arcLengthCircle << std::endl;
2064  std::cout << "\ttheoretical length =" << theoreticalValue << std::endl;
2065  std::cout << "\ttest status = " << statusTest << std::endl;
2066 
2067  hasSucceeded &= isValueOK;
2068  }
2069 
2070  // Test intersections with all the axis
2071  {
2072  // Choosing theta_v_left_min = 7 PI / 8 and circle at the center of the RoI
2073  // umin = uc + r cos(theta_v_left_min) => r = (umin - uc) / cos(theta_v_left_min)
2074  vpRect squareRoI(OFFSET, OFFSET, HEIGHT, HEIGHT);
2075  float theta_v_left_min = 7.f * M_PIf / 8.f;
2076  float uc = OFFSET + HEIGHT / 2.f;
2077  float vc = OFFSET + HEIGHT / 2.f;
2078  float radius = (OFFSET - uc) / std::cos(theta_v_left_min);
2079 
2080  vpImageCircle circle(vpImagePoint(vc, uc), radius);
2081  float arcLengthCircle = circle.computeArcLengthInRoI(squareRoI);
2082  float theoreticalValue = M_PIf * radius;
2083  bool isValueOK = equal(arcLengthCircle, theoreticalValue);
2084  std::string statusTest;
2085  if (isValueOK) {
2086  statusTest = "SUCCESS";
2087  }
2088  else {
2089  statusTest = "FAILED";
2090  }
2091  std::cout << "Test with intersections with the top and bottom borders only, crossing each axis twice in the RoI." << std::endl;
2092  std::cout << "\tarc length =" << arcLengthCircle << std::endl;
2093  std::cout << "\ttheoretical length =" << theoreticalValue << std::endl;
2094  std::cout << "\ttest status = " << statusTest << std::endl;
2095 
2096  hasSucceeded &= isValueOK;
2097  }
2098 
2099  if (hasSucceeded) {
2100  std::cout << "testImageCircle overall result: SUCCESS" << std::endl;
2101  return EXIT_SUCCESS;
2102  }
2103 
2104  std::cout << "testImageCircle overall result: FAILED" << std::endl;
2105  return EXIT_FAILURE;
2106 }
Class that defines a 2D circle in an image.
Definition: vpImageCircle.h:56
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
Definition: vpImagePoint.h:82
static float getAngleBetweenMinPiAndPi(const float &theta)
Definition: vpMath.h:137
Defines a rectangle in the plane.
Definition: vpRect.h:76