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