Visual Servoing Platform version 3.7.0
Loading...
Searching...
No Matches
vpPlane.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 * Plane geometrical structure.
32 */
33
38
39#include <visp3/core/vpPlane.h>
40
41#include <cmath> // std::fabs
42#include <limits> // numeric_limits
43
49{
50 A = p.A;
51 B = p.B;
52 C = p.C;
53 D = p.D;
54
55 return *this;
56}
57
61vpPlane::vpPlane() : A(0), B(0), C(0), D(0) { }
62
75vpPlane::vpPlane(double a, double b, double c, double d) : A(a), B(b), C(c), D(d) { }
76
80vpPlane::vpPlane(const vpPlane &P) : A(0), B(0), C(0), D(0)
81{
82 setA(P.getA());
83 setB(P.getB());
84 setC(P.getC());
85 setD(P.getD());
86}
87
108vpPlane::vpPlane(const vpPoint &P, const vpColVector &normal, const vpPlaneFrame &frame) : A(0), B(0), C(0), D(0)
109{
110 const unsigned int index_0 = 0;
111 const unsigned int index_1 = 1;
112 const unsigned int index_2 = 2;
113 // Equation of the plane is given by:
114 A = normal[index_0];
115 B = normal[index_1];
116 C = normal[index_2];
117
118 if (frame == vpPlane::camera_frame) {
119 D = -((A * P.get_X()) + (B * P.get_Y()) + (C * P.get_Z()));
120 }
121 else {
122 D = -((A * P.get_oX()) + (B * P.get_oY()) + (C * P.get_oZ()));
123 }
124}
125
132{
133 setA(P.getA());
134 setB(P.getB());
135 setC(P.getC());
136 setD(P.getD());
137
138 return *this;
139}
140
159vpPlane &vpPlane::init(const vpPoint &P, const vpColVector &normal, const vpPlaneFrame &frame)
160{
161 const unsigned int index_0 = 0;
162 const unsigned int index_1 = 1;
163 const unsigned int index_2 = 2;
164 // Equation of the plane is given by:
165 A = normal[index_0];
166 B = normal[index_1];
167 C = normal[index_2];
168
169 if (frame == vpPlane::camera_frame) {
170 D = -((A * P.get_X()) + (B * P.get_Y()) + (C * P.get_Z()));
171 }
172 else {
173 D = -((A * P.get_oX()) + (B * P.get_oY()) + (C * P.get_oZ()));
174 }
175
176 return *this;
177}
178
191{
192 const unsigned int index_0 = 0;
193 const unsigned int index_1 = 1;
194 const unsigned int index_2 = 2;
195 // Equation of the plane is given by:
196 A = normal[index_0];
197 B = normal[index_1];
198 C = normal[index_2];
199
200 D = -((A * P[0]) + (B * P[1]) + (C * P[index_2]));
201
202 return *this;
203}
204
218vpPlane &vpPlane::init(const vpPoint &P, const vpPoint &Q, const vpPoint &R, const vpPlaneFrame &frame)
219{
220 vpColVector a(3);
221 vpColVector b(3);
222 vpColVector n(3);
223 const unsigned int index_0 = 0;
224 const unsigned int index_1 = 1;
225 const unsigned int index_2 = 2;
226 if (frame == vpPlane::camera_frame) {
227 // Calculate vector corresponding to PQ
228 a[index_0] = P.get_X() - Q.get_X();
229 a[index_1] = P.get_Y() - Q.get_Y();
230 a[index_2] = P.get_Z() - Q.get_Z();
231
232 // Calculate vector corresponding to PR
233 b[index_0] = P.get_X() - R.get_X();
234 b[index_1] = P.get_Y() - R.get_Y();
235 b[index_2] = P.get_Z() - R.get_Z();
236 }
237 else {
238 // Calculate vector corresponding to PQ
239 a[index_0] = P.get_oX() - Q.get_oX();
240 a[index_1] = P.get_oY() - Q.get_oY();
241 a[index_2] = P.get_oZ() - Q.get_oZ();
242
243 // Calculate vector corresponding to PR
244 b[index_0] = P.get_oX() - R.get_oX();
245 b[index_1] = P.get_oY() - R.get_oY();
246 b[index_2] = P.get_oZ() - R.get_oZ();
247 }
248 // Calculate normal vector to plane PQ x PR
249 n = vpColVector::cross(a, b);
250
251 // Equation of the plane is given by:
252 A = n[index_0];
253 B = n[index_1];
254 C = n[index_2];
255 if (frame == vpPlane::camera_frame) {
256 D = -((A * P.get_X()) + (B * P.get_Y()) + (C * P.get_Z()));
257 }
258 else {
259 D = -((A * P.get_oX()) + (B * P.get_oY()) + (C * P.get_oZ()));
260 }
261
262 double norm = sqrt((A * A) + (B * B) + (C * C));
263 A /= norm;
264 B /= norm;
265 C /= norm;
266 D /= norm;
267
268 return *this;
269}
270
285vpPlane::vpPlane(const vpPoint &P, const vpPoint &Q, const vpPoint &R, const vpPlaneFrame &frame) : A(0), B(0), C(0), D(0)
286{
287 init(P, Q, R, frame);
288}
289
298double vpPlane::computeZ(double x, double y) const
299{
300 return -getD() / ((getA() * x) + (getB() * y) + getC());
301}
302
312{
313 const unsigned int val_3 = 3;
314 vpColVector n(val_3);
315 const unsigned int index_0 = 0;
316 const unsigned int index_1 = 1;
317 const unsigned int index_2 = 2;
318 n[index_0] = A;
319 n[index_1] = B;
320 n[index_2] = C;
321
322 return n;
323}
324
336{
337 const unsigned int val_3 = 3;
338 n.resize(val_3);
339 const unsigned int index_0 = 0;
340 const unsigned int index_1 = 1;
341 const unsigned int index_2 = 2;
342 n[index_0] = A;
343 n[index_1] = B;
344 n[index_2] = C;
345}
346
358void vpPlane::projectionPointOnPlan(const vpPoint &P, vpPoint &Pproj, const vpPlaneFrame &frame) const
359{
360 double x0, y0, z0;
361 double rho;
362
363 if (frame == vpPlane::camera_frame) {
364 x0 = P.get_X() / P.get_W();
365 y0 = P.get_Y() / P.get_W();
366 z0 = P.get_Z() / P.get_W();
367
368 rho = -((A * x0) + (B * y0) + (C * z0) + D) / ((A * A) + (B * B) + (C * C));
369
370 Pproj.set_X(x0 + (A * rho));
371 Pproj.set_Y(y0 + (B * rho));
372 Pproj.set_Z(z0 + (C * rho));
373 Pproj.set_W(1);
374 }
375 else {
376 x0 = P.get_oX() / P.get_oW();
377 y0 = P.get_oY() / P.get_oW();
378 z0 = P.get_oZ() / P.get_oW();
379
380 rho = -((A * x0) + (B * y0) + (C * z0) + D) / ((A * A) + (B * B) + (C * C));
381
382 Pproj.set_oX(x0 + (A * rho));
383 Pproj.set_oY(y0 + (B * rho));
384 Pproj.set_oZ(z0 + (C * rho));
385 Pproj.set_oW(1);
386 }
387}
388
389double vpPlane::rayIntersection(const vpPoint &M0, const vpPoint &M1, vpColVector &H) const
390{
391 double k, scal;
392 const unsigned int index_0 = 0;
393 const unsigned int index_1 = 1;
394 const unsigned int index_2 = 2;
395
396 // --comment: if M0.get_X() diff 0 or M0.get_Y() diff 0 or M0.get_Z() diff 0
397 if ((std::fabs(M0.get_X()) > std::numeric_limits<double>::epsilon()) ||
398 (std::fabs(M0.get_Y()) > std::numeric_limits<double>::epsilon()) ||
399 (std::fabs(M0.get_Z()) > std::numeric_limits<double>::epsilon())) {
400 double R[3];
401 R[index_0] = M1.get_X() - M0.get_X();
402 R[index_1] = M1.get_Y() - M0.get_Y();
403 R[index_2] = M1.get_Z() - M0.get_Z();
404
405 scal = (getA() * R[index_0]) + (getB() * R[index_1]) + (getC() * R[index_2]);
406 // --comment: if scal != 0
407 if (std::fabs(scal) > std::numeric_limits<double>::epsilon()) {
408 k = -((getA() * M0.get_X()) + (getB() * M0.get_Y()) + (getC() * M0.get_Z()) + getD()) / scal;
409 }
410 else {
411 k = 0;
412 }
413
414 H[index_0] = M0.get_X() + (k * R[index_0]);
415 H[index_1] = M0.get_Y() + (k * R[index_1]);
416 H[index_2] = M0.get_Z() + (k * R[index_2]);
417 }
418 else {
419 scal = (getA() * M1.get_X()) + (getB() * M1.get_Y()) + (getC() * M1.get_Z());
420 // --comment: if scal != 0
421 if (std::fabs(scal) > std::numeric_limits<double>::epsilon()) {
422 k = -getD() / scal;
423 }
424 else {
425 k = 0;
426 }
427 H[index_0] = k * M1.get_X();
428 H[index_1] = k * M1.get_Y();
429 H[index_2] = k * M1.get_Z();
430 }
431
432 return k;
433}
434
436{
437 double k, scal;
438 const unsigned int index_0 = 0;
439 const unsigned int index_1 = 1;
440 const unsigned int index_2 = 2;
441
442 scal = (A * M1[index_0]) + (B * M1[index_1]) + (C * M1[index_2]);
443 // --comment: if scal != 0
444 if (std::fabs(scal) > std::numeric_limits<double>::epsilon()) {
445 k = -getD() / scal;
446 }
447 else {
448 k = 0;
449 }
450 H[index_0] = k * M1[index_0];
451 H[index_1] = k * M1[index_1];
452 H[index_2] = k * M1[index_2];
453
454 return k;
455}
456
466{
467 // Save current plane parameters
468 double Ao = A;
469 double Bo = B;
470 double Co = C;
471 double Do = D;
472 const unsigned int index_0 = 0;
473 const unsigned int index_1 = 1;
474 const unsigned int index_2 = 2;
475 const unsigned int index_3 = 3;
476 A = (cMo[index_0][0] * Ao) + (cMo[index_0][1] * Bo) + (cMo[index_0][index_2] * Co);
477 B = (cMo[index_1][0] * Ao) + (cMo[index_1][1] * Bo) + (cMo[index_1][index_2] * Co);
478 C = (cMo[index_2][0] * Ao) + (cMo[index_2][1] * Bo) + (cMo[index_2][index_2] * Co);
479 D = Do - ((cMo[index_0][index_3] * A) + (cMo[index_1][index_3] * B) + (cMo[index_2][index_3] * C));
480}
481
488VISP_EXPORT std::ostream &operator<<(std::ostream &os, const vpPlane &p)
489{
490 return (os << "(" << p.getA() << "," << p.getB() << "," << p.getC() << "," << p.getD() << ") ");
491}
492END_VISP_NAMESPACE
Implementation of column vector and the associated operations.
static vpColVector cross(const vpColVector &a, const vpColVector &b)
void resize(unsigned int i, bool flagNullify=true)
Implementation of an homogeneous matrix and operations on such kind of matrices.
vpPlane & init(const vpPoint &P, const vpColVector &normal, const vpPlaneFrame &frame=camera_frame)
Definition vpPlane.cpp:159
double C
Definition vpPlane.h:60
friend VISP_EXPORT std::ostream & operator<<(std::ostream &os, const vpPlane &p)
Definition vpPlane.cpp:488
vpPlaneFrame
Definition vpPlane.h:64
@ camera_frame
Definition vpPlane.h:64
double rayIntersection(const vpPoint &M0, const vpPoint &M1, vpColVector &H) const
Definition vpPlane.cpp:389
void changeFrame(const vpHomogeneousMatrix &cMo)
Definition vpPlane.cpp:465
void setA(double a)
Definition vpPlane.h:80
void setD(double d)
Definition vpPlane.h:86
double A
Definition vpPlane.h:60
double D
Definition vpPlane.h:60
double computeZ(double x, double y) const
Definition vpPlane.cpp:298
double getD() const
Definition vpPlane.h:106
void setC(double c)
Definition vpPlane.h:84
double B
Definition vpPlane.h:60
vpColVector getNormal() const
Definition vpPlane.cpp:311
double getA() const
Definition vpPlane.h:100
double getC() const
Definition vpPlane.h:104
double getB() const
Definition vpPlane.h:102
void projectionPointOnPlan(const vpPoint &P, vpPoint &Pproj, const vpPlaneFrame &frame=camera_frame) const
Definition vpPlane.cpp:358
vpPlane & operator=(const vpPlane &f)
Definition vpPlane.cpp:48
vpPlane()
Definition vpPlane.cpp:61
void setB(double b)
Definition vpPlane.h:82
double getIntersection(const vpColVector &M1, vpColVector &H) const
Definition vpPlane.cpp:435
Class that defines a 3D point in the object frame and allows forward projection of a 3D point in the ...
Definition vpPoint.h:79
double get_oW() const
Get the point oW coordinate in the object frame.
Definition vpPoint.cpp:424
double get_oX() const
Get the point oX coordinate in the object frame.
Definition vpPoint.cpp:418
void set_W(double cW)
Set the point cW coordinate in the camera frame.
Definition vpPoint.cpp:459
void set_oW(double oW)
Set the point oW coordinate in the object frame.
Definition vpPoint.cpp:468
double get_Y() const
Get the point cY coordinate in the camera frame.
Definition vpPoint.cpp:411
double get_oZ() const
Get the point oZ coordinate in the object frame.
Definition vpPoint.cpp:422
void set_oY(double oY)
Set the point oY coordinate in the object frame.
Definition vpPoint.cpp:464
void set_X(double cX)
Set the point cX coordinate in the camera frame.
Definition vpPoint.cpp:453
double get_W() const
Get the point cW coordinate in the camera frame.
Definition vpPoint.cpp:415
void set_Y(double cY)
Set the point cY coordinate in the camera frame.
Definition vpPoint.cpp:455
double get_Z() const
Get the point cZ coordinate in the camera frame.
Definition vpPoint.cpp:413
void set_oZ(double oZ)
Set the point oZ coordinate in the object frame.
Definition vpPoint.cpp:466
void set_Z(double cZ)
Set the point cZ coordinate in the camera frame.
Definition vpPoint.cpp:457
void set_oX(double oX)
Set the point oX coordinate in the object frame.
Definition vpPoint.cpp:462
double get_oY() const
Get the point oY coordinate in the object frame.
Definition vpPoint.cpp:420
double get_X() const
Get the point cX coordinate in the camera frame.
Definition vpPoint.cpp:409