Visual Servoing Platform version 3.7.0
Loading...
Searching...
No Matches
vpProjection.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 * Le module "projection.c" contient les procedures de calcul
32 * des matrices de projection perspective et parallele.
33 *
34 * Authors:
35 * Jean-Luc CORRE
36 */
37
38#include <visp3/core/vpConfig.h>
39
40#ifndef DOXYGEN_SHOULD_SKIP_THIS
41#include "vpProjection.h"
42#include <math.h>
43#include <stdio.h>
44
46/*
47 * La procedure "View_to_Matrix" constuit la matrice homogene de projection
48 * a partir des parametres de la prise de vue.
49 * Entree :
50 * vp Parametres de la prise de vue.
51 * m Matrice homogene a construire.
52 */
53 void View_to_Matrix(View_parameters *vp, Matrix m)
54{
55 static char proc_name[] = "View_to_Matrix";
56
57 switch (vp->type) {
58 case PARALLEL:
59 set_parallel(vp, m);
60 break;
61 case PERSPECTIVE:
62 set_perspective(vp, m);
63 break;
64 default:
65 fprintf(stderr, "%s: bad view type\n", proc_name);
66 set_perspective(vp, m);
67 break;
68 }
69}
70
71/*
72 * La procedure "set_zy" initialise la matrice par une composition :
73 * 1 - aligne le premier vecteur sur l'axe Z dans le sens negatif.
74 * 2 - aligne la projection du second vecteur sur l'axe Y.
75 * Entree :
76 * m Matrice a initialiser.
77 * v0 Premier vecteur.
78 * v1 Second vecteur.
79 */
80static void set_zy(Matrix m, Vector *v0, Vector *v1)
81{
82 Vector rx, ry, rz;
83
84 SET_COORD3(rz, -v0->x, -v0->y, -v0->z);
85 CROSS_PRODUCT(rx, *v0, *v1);
86 norm_vector(&rx);
87 norm_vector(&rz);
88 CROSS_PRODUCT(ry, rz, rx); /* ry est norme */
89
90 m[0][0] = rx.x;
91 m[0][1] = ry.x;
92 m[0][2] = rz.x;
93 m[0][3] = 0.0;
94 m[1][0] = rx.y;
95 m[1][1] = ry.y;
96 m[1][2] = rz.y;
97 m[1][3] = 0.0;
98 m[2][0] = rx.z;
99 m[2][1] = ry.z;
100 m[2][2] = rz.z;
101 m[2][3] = 0.0;
102 m[3][0] = 0.0;
103 m[3][1] = 0.0;
104 m[3][2] = 0.0;
105 m[3][3] = 1.0;
106}
107
108/*
109 * La procedure "set_parallel" iniatilise la matrice de projection
110 * parallel "wc" par les parametres de visualisation "vp".
111 * Pour plus de renseignements :
112 * "Fundamentals of Interactive Computer Graphics"
113 * J.D. FOLEY, A. VAN DAM, Addison-Wesley. 1982, pp 285-290.
114 * Entree :
115 * vp Parametres de visualisation.
116 * wc Matrice a initialiser.
117 */
118void set_parallel(View_parameters *vp, Matrix wc)
119{
120 Matrix m = IDENTITY_MATRIX;
121 Point3f cop;
122 Point4f doprim;
123 Vector dop, v;
124
125 /*
126 * 1 : Translation du point de reference VRP a l'origine.
127 */
128 SET_COORD3(v, -vp->vrp.x, -vp->vrp.y, -vp->vrp.z);
129 Translate_to_Matrix(&v, wc);
130 /*
131 * 2 : Rotation pour rendre VPN parallele a l'axe des Z negatifs.
132 * 3 : Rotation pour rendre la projection de VUP sur le plan de
133 * projection parallele a l'axe Y.
134 */
135 set_zy(m, &vp->vpn, &vp->vup);
136 /*
137 * 4 : Passer d'un repere droit (absolu) a un repere gauche (vision).
138 */
139 postleft_matrix(m, 'z');
140 postmult_matrix(wc, m);
141 /*
142 * 5 : Alignement de l'axe central du volume de vision sur l'axe Z.
143 * COP = DOP = Direction of Projection.
144 * DOPRIM = DOP * R_TRL
145 * Pas de translation dans la matrice R_TRL pour la transformation
146 * du vecteur DOP.
147 */
148 SET_COORD3(dop, vp->vrp.x - vp->cop.x, vp->vrp.y - vp->cop.y, vp->vrp.z - vp->cop.z);
149 norm_vector(&dop);
150 SET_COORD3(cop, dop.x, dop.y, dop.z);
151 point_matrix(&doprim, &cop, m);
152 ident_matrix(m);
153 m[2][0] = -doprim.x / doprim.z;
154 m[2][1] = -doprim.y / doprim.z;
155 postmult_matrix(wc, m);
156 /*
157 * 6 : Translation et Mise a l'echelle de la pyramide.
158 * Remarque : contrairement a la reference qui donne
159 * 0 < x < 1, 0 < y < 1, 0 < z < 1
160 * je prefere, afin de rester coherent avec la projection perspective,
161 * -1 < x < 1, -1 < y < 1, 0 < z < 1 (w = 1)
162 */
163 SET_COORD3(v, static_cast<float>(-(vp->vwd.umax + vp->vwd.umin) / 2.0), static_cast<float>(-(vp->vwd.vmax + vp->vwd.vmin) / 2.0),
164 static_cast<float>(vp->depth.front));
165 posttrans_matrix(wc, &v);
166 SET_COORD3(v, static_cast<float>(2.0 / (vp->vwd.umax - vp->vwd.umin)), static_cast<float>(2.0 / (vp->vwd.vmax - vp->vwd.vmin)),
167 static_cast<float>(1.0 / (vp->depth.back - vp->depth.front)));
168 postscale_matrix(wc, &v);
169}
170
171/*
172 * La procedure "set_perspective" iniatilise la matrice de projection
173 * perspective "wc" par les parametres de visualisation "vp".
174 * Pour plus de renseignements :
175 * "Fundamentals of Interactive Computer Graphics"
176 * J.D. FOLEY, A. VAN DAM, Addison-Wesley. 1982, pp 290-302.
177 * Entree :
178 * vp Parametres de visualisation.
179 * wc Matrice a initialiser.
180 */
181void set_perspective(View_parameters *vp, Matrix wc)
182{
183 Matrix m = IDENTITY_MATRIX;
184 Point4f vrprim, cw;
185 float zmin;
186 Vector v;
187
188 /*
189 * 1 : Translation du centre de projection COP a l'origine.
190 */
191 SET_COORD3(v, -vp->cop.x, -vp->cop.y, -vp->cop.z);
192 Translate_to_Matrix(&v, wc);
193 /*
194 * 2 : Rotation pour rendre VPN parallele a l'axe des Z negatifs.
195 * 3 : Rotation pour rendre la projection de VUP sur le plan de
196 * projection parallele a l'axe Y.
197 */
198 set_zy(m, &vp->vpn, &vp->vup);
199 postmult_matrix(wc, m);
200 /*
201 * 4 : Passer d'un repere droit (absolu) a un repere gauche (vision).
202 */
203 postleft_matrix(wc, 'z');
204 /*
205 * 5 : Alignement de l'axe central du volume de vision sur l'axe Z.
206 */
207 point_matrix(&vrprim, &vp->vrp, wc);
208 cw.x = static_cast<float>(vrprim.x + (vp->vwd.umin + vp->vwd.umax) / 2.0);
209 cw.y = static_cast<float>(vrprim.y + (vp->vwd.vmin + vp->vwd.vmax) / 2.0);
210 cw.z = static_cast<float>(vrprim.z);
211 ident_matrix(m);
212 m[2][0] = -cw.x / cw.z;
213 m[2][1] = -cw.y / cw.z;
214 postmult_matrix(wc, m);
215 /*
216 * 6 : Mise a l'echelle de la pyramide.
217 */
218 SET_COORD3(v, static_cast<float>((2.0 * vrprim.z) / ((vp->vwd.umax - vp->vwd.umin) * (vrprim.z + vp->depth.back))),
219 static_cast<float>((2.0 * vrprim.z) / ((vp->vwd.vmax - vp->vwd.vmin) * (vrprim.z + vp->depth.back))),
220 static_cast<float>(1.0 / (vrprim.z + vp->depth.back)));
221 postscale_matrix(wc, &v);
222 /*
223 * 7 : Transformation perspective.
224 */
225 zmin = (vrprim.z + vp->depth.front) / (vrprim.z + vp->depth.back);
226 ident_matrix(m);
227 m[2][2] = static_cast<float>(1.0 / (1.0 - zmin));
228 m[2][3] = 1.0;
229 m[3][2] = static_cast<float>(-zmin / (1.0 - zmin));
230 m[3][3] = 0.0;
231 postmult_matrix(wc, m);
232}
233END_VISP_NAMESPACE
234#endif