Visual Servoing Platform version 3.7.0
Loading...
Searching...
No Matches
vpLine.cpp
1/*
2 * ViSP, open source Visual Servoing Platform software.
3 * Copyright (C) 2005 - 2025 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 * Line feature.
32 */
33
38
39#include <visp3/core/vpLine.h>
40
41#include <visp3/core/vpMath.h>
42
43#include <visp3/core/vpFeatureDisplay.h>
44
52{
53 const unsigned int val_2 = 2;
54 const unsigned int val_8 = 8;
55 oP.resize(val_8);
56 cP.resize(val_8);
57 p.resize(val_2);
58}
59
64
87void vpLine::setWorldCoordinates(const double &oA1, const double &oB1, const double &oC1, const double &oD1,
88 const double &oA2, const double &oB2, const double &oC2, const double &oD2)
89{
90 const unsigned int index_0 = 0;
91 const unsigned int index_1 = 1;
92 const unsigned int index_2 = 2;
93 const unsigned int index_3 = 3;
94 const unsigned int index_4 = 4;
95 const unsigned int index_5 = 5;
96 const unsigned int index_6 = 6;
97 const unsigned int index_7 = 7;
98 oP[index_0] = oA1;
99 oP[index_1] = oB1;
100 oP[index_2] = oC1;
101 oP[index_3] = oD1;
102
103 oP[index_4] = oA2;
104 oP[index_5] = oB2;
105 oP[index_6] = oC2;
106 oP[index_7] = oD2;
107}
108
128{
129 const unsigned int val_8 = 8;
130 if (oP_.getRows() != val_8) {
131 throw vpException(vpException::dimensionError, "Size of oP is not equal to 8 as it should be");
132 }
133 this->oP = oP_;
134}
135
158{
159 const unsigned int val_4 = 4;
160 if (oP1.getRows() != val_4) {
161 throw vpException(vpException::dimensionError, "Size of oP1 is not equal to 4 as it should be");
162 }
163 if (oP2.getRows() != val_4) {
164 throw vpException(vpException::dimensionError, "Size of oP2 is not equal to 4 as it should be");
165 }
166 for (unsigned int i = 0; i < val_4; ++i) {
167 oP[i] = oP1[i];
168 oP[i + val_4] = oP2[i];
169 }
170}
171
206
225void vpLine::projection(const vpColVector &cP_, vpColVector &p_) const
226{
227 const unsigned int val_2 = 2;
228 const unsigned int val_8 = 8;
229 p_.resize(val_2, false);
230 // projection
231
232 if (cP.getRows() != val_8) {
233 throw vpException(vpException::dimensionError, "Size of cP is not equal to 8 as it should be");
234 }
235 double A1, A2, B1, B2, C1, C2, D1, D2;
236 const unsigned int index_0 = 0;
237 const unsigned int index_1 = 1;
238 const unsigned int index_2 = 2;
239 const unsigned int index_3 = 3;
240 const unsigned int index_4 = 4;
241 const unsigned int index_5 = 5;
242 const unsigned int index_6 = 6;
243 const unsigned int index_7 = 7;
244
245 A1 = cP_[index_0];
246 B1 = cP_[index_1];
247 C1 = cP_[index_2];
248 D1 = cP_[index_3];
249
250 A2 = cP_[index_4];
251 B2 = cP_[index_5];
252 C2 = cP_[index_6];
253 D2 = cP_[index_7];
254
255 double a, b, c, s;
256 a = (A2 * D1) - (A1 * D2);
257 b = (B2 * D1) - (B1 * D2);
258 c = (C2 * D1) - (C1 * D2);
259 s = (a * a) + (b * b);
260 if (s <= 1e-8) // seuil pas terrible
261 {
262 printf("Degenerate case: the image of the straight line is a point!\n");
263 throw vpException(vpException::fatalError, "Degenerate case: the image of the straight line is a point!");
264 }
265 s = 1.0 / sqrt(s);
266
267 double rho = -c * s;
268 double theta = atan2(b, a);
269
270 p_[0] = rho;
271 p_[1] = theta;
272}
273
311
353{
354 const unsigned int val_8 = 8;
355 cP_.resize(val_8, false);
356
357 double a1, a2, b1, b2, c1, c2, d1, d2;
358 double A1, A2, B1, B2, C1, C2, D1, D2;
359 const unsigned int index_0 = 0;
360 const unsigned int index_1 = 1;
361 const unsigned int index_2 = 2;
362 const unsigned int index_3 = 3;
363 const unsigned int index_4 = 4;
364 const unsigned int index_5 = 5;
365 const unsigned int index_6 = 6;
366 const unsigned int index_7 = 7;
367
368 // in case of verification
369 // double x,y,z,ap1,ap2,bp1,bp2,cp1,cp2,dp1,dp2;
370
371 a1 = oP[index_0];
372 b1 = oP[index_1];
373 c1 = oP[index_2];
374 d1 = oP[index_3];
375
376 a2 = oP[index_4];
377 b2 = oP[index_5];
378 c2 = oP[index_6];
379 d2 = oP[index_7];
380
381 A1 = (cMo[index_0][0] * a1) + (cMo[index_0][1] * b1) + (cMo[index_0][index_2] * c1);
382 B1 = (cMo[index_1][0] * a1) + (cMo[index_1][1] * b1) + (cMo[index_1][index_2] * c1);
383 C1 = (cMo[index_2][0] * a1) + (cMo[index_2][1] * b1) + (cMo[index_2][index_2] * c1);
384 D1 = d1 - ((cMo[index_0][index_3] * A1) + (cMo[index_1][index_3] * B1) + (cMo[index_2][index_3] * C1));
385
386 A2 = (cMo[index_0][0] * a2) + (cMo[index_0][1] * b2) + (cMo[index_0][index_2] * c2);
387 B2 = (cMo[index_1][0] * a2) + (cMo[index_1][1] * b2) + (cMo[index_1][index_2] * c2);
388 C2 = (cMo[index_2][0] * a2) + (cMo[index_2][1] * b2) + (cMo[index_2][index_2] * c2);
389 D2 = d2 - ((cMo[index_0][index_3] * A2) + (cMo[index_1][index_3] * B2) + (cMo[index_2][index_3] * C2));
390
391 // Adding constraints on the straight line to have a unique representation
392
393 // direction of the straight line = N1 x N2
394 a2 = (B1 * C2) - (C1 * B2);
395 b2 = (C1 * A2) - (A1 * C2);
396 c2 = (A1 * B2) - (B1 * A2);
397
398 // Constraint D1 = 0 (the origin belongs to P1)
399 a1 = (A2 * D1) - (A1 * D2);
400 b1 = (B2 * D1) - (B1 * D2);
401 c1 = (C2 * D1) - (C1 * D2);
402
403 if (fabs(D2) < fabs(D1)) // to be sure that D2 <> 0
404 {
405 A2 = A1;
406 B2 = B1;
407 C2 = C1;
408 D2 = D1;
409 }
410
411 // Constraint A1^2 + B1^2 + C1^2 = 1
412 d1 = 1.0 / sqrt((a1 * a1) + (b1 * b1) + (c1 * c1));
413 A1 = a1 * d1;
414 B1 = b1 * d1;
415 C1 = c1 * d1;
416 cP_[index_0] = A1;
417 cP_[index_1] = B1;
418 cP_[index_2] = C1;
419
420 cP_[index_3] = 0;
421
422 // Constraint A1 A2 + B1 B2 + C1 C2 = 0 (P2 orthogonal to P1)
423 // N2_new = (N1 x N2) x N1_new
424 a1 = (b2 * C1) - (c2 * B1);
425 b1 = (c2 * A1) - (a2 * C1);
426 c1 = (a2 * B1) - (b2 * A1);
427
428 // Constraint A2^2 + B2^2 + C2^2 = 1
429 d1 = 1.0 / sqrt((a1 * a1) + (b1 * b1) + (c1 * c1));
430 a1 *= d1;
431 b1 *= d1;
432 c1 *= d1;
433
434 // D2_new = D2 / (N2^T . N2_new)
435 D2 /= ((A2 * a1) + (B2 * b1) + (C2 * c1));
436 A2 = a1;
437 B2 = b1;
438 C2 = c1;
439
440 // Constraint D2 < 0
441 if (D2 > 0) {
442 A2 = -A2;
443 B2 = -B2;
444 C2 = -C2;
445 D2 = -D2;
446 }
447
448 cP_[index_4] = A2;
449 cP_[index_5] = B2;
450 cP_[index_6] = C2;
451 cP_[index_7] = D2;
452}
453
470void vpLine::display(const vpImage<unsigned char> &I, const vpCameraParameters &cam, const vpColor &color,
471 unsigned int thickness)
472{
473 vpFeatureDisplay::displayLine(p[0], p[1], cam, I, color, thickness);
474}
475
491void vpLine::display(const vpImage<vpRGBa> &I, const vpCameraParameters &cam, const vpColor &color,
492 unsigned int thickness)
493{
494 vpFeatureDisplay::displayLine(p[0], p[1], cam, I, color, thickness);
495}
496
520 const vpColor &color, unsigned int thickness)
521{
522 vpColVector v_cP, v_p;
523 changeFrame(cMo, v_cP);
524 try {
525 projection(v_cP, v_p);
526 vpFeatureDisplay::displayLine(v_p[0], v_p[1], cam, I, color, thickness);
527 }
528 catch (...) {
529 // Skip potential exception: due to a degenerate case: the image of the straight line is a point!
530 }
531}
532
556 const vpColor &color, unsigned int thickness)
557{
558 vpColVector v_cP, v_p;
559 changeFrame(cMo, v_cP);
560 try {
561 projection(v_cP, v_p);
562 vpFeatureDisplay::displayLine(v_p[0], v_p[1], cam, I, color, thickness);
563 }
564 catch (...) {
565 // Skip potential exception: due to a degenerate case: the image of the straight line is a point!
566 }
567}
568
580{
581 vpLine *feature = new vpLine(*this);
582 return feature;
583}
584END_VISP_NAMESPACE
unsigned int getRows() const
Definition vpArray2D.h:433
Generic class defining intrinsic camera parameters.
Implementation of column vector and the associated operations.
void resize(unsigned int i, bool flagNullify=true)
Class to define RGB colors available for display functionalities.
Definition vpColor.h:157
error that can be emitted by ViSP classes.
Definition vpException.h:60
@ dimensionError
Bad dimension.
Definition vpException.h:71
@ fatalError
Fatal error.
Definition vpException.h:72
static void displayLine(double rho, double theta, const vpCameraParameters &cam, const vpImage< unsigned char > &I, const vpColor &color=vpColor::green, unsigned int thickness=1)
Implementation of an homogeneous matrix and operations on such kind of matrices.
Definition of the vpImage class member functions.
Definition vpImage.h:131
void projection() VP_OVERRIDE
Definition vpLine.cpp:205
vpLine * duplicate() const VP_OVERRIDE
Definition vpLine.cpp:579
void changeFrame(const vpHomogeneousMatrix &cMo, vpColVector &cP) const VP_OVERRIDE
Definition vpLine.cpp:352
vpLine()
Definition vpLine.cpp:63
void display(const vpImage< unsigned char > &I, const vpCameraParameters &cam, const vpColor &color=vpColor::green, unsigned int thickness=1) VP_OVERRIDE
Definition vpLine.cpp:470
void init() VP_OVERRIDE
Definition vpLine.cpp:51
void setWorldCoordinates(const double &oA1, const double &oB1, const double &oC1, const double &oD1, const double &oA2, const double &oB2, const double &oC2, const double &oD2)
Definition vpLine.cpp:87
vpColVector cP
Definition vpTracker.h:73
vpColVector p
Definition vpTracker.h:69