ViSP  3.0.0
vpProjection.cpp
1 /****************************************************************************
2  *
3  * This file is part of the ViSP software.
4  * Copyright (C) 2005 - 2015 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * ("GPL") version 2 as published by the Free Software Foundation.
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 http://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 
39 
40 
41 
42 
43 
44 #include <visp3/core/vpConfig.h>
45 
46 #ifndef DOXYGEN_SHOULD_SKIP_THIS
47 #include <visp3/robot/vpMy.h>
48 #include <visp3/robot/vpArit.h>
49 #include <visp3/robot/vpView.h>
50 #include <stdio.h>
51 #include <math.h>
52 void set_parallel (View_parameters*, Matrix);
53 void set_perspective (View_parameters*, Matrix);
54 
55 
56 
57 /*
58  * La procedure "View_to_Matrix" constuit la matrice homogene de projection
59  * a partir des parametres de la prise de vue.
60  * Entree :
61  * vp Parametres de la prise de vue.
62  * m Matrice homogene a construire.
63  */
64 void View_to_Matrix (View_parameters *vp, Matrix m)
65 {
66  static char proc_name[] = "View_to_Matrix";
67 
68  switch (vp->type) {
69  case PARALLEL :
70  set_parallel (vp, m);
71  break;
72  case PERSPECTIVE :
73  set_perspective (vp, m);
74  break;
75  default :
76  fprintf (stderr, "%s: bad view type\n", proc_name);
77  set_perspective (vp, m);
78  break;
79  }
80 }
81 
82 
83 /*
84  * La procedure "set_zy" initialise la matrice par une composition :
85  * 1 - aligne le premier vecteur sur l'axe Z dans le sens negatif.
86  * 2 - aligne la projection du second vecteur sur l'axe Y.
87  * Entree :
88  * m Matrice a initialiser.
89  * v0 Premier vecteur.
90  * v1 Second vecteur.
91  */
92 static void set_zy (Matrix m, Vector *v0, Vector *v1)
93 {
94  Vector rx, ry, rz;
95 
96  SET_COORD3(rz, - v0->x,- v0->y, - v0->z);
97  CROSS_PRODUCT(rx, *v0, *v1);
98  norm_vector (&rx);
99  norm_vector (&rz);
100  CROSS_PRODUCT (ry,rz,rx); /* ry est norme */
101 
102  m[0][0] = rx.x; m[0][1] = ry.x; m[0][2] = rz.x; m[0][3] = 0.0;
103  m[1][0] = rx.y; m[1][1] = ry.y; m[1][2] = rz.y; m[1][3] = 0.0;
104  m[2][0] = rx.z; m[2][1] = ry.z; m[2][2] = rz.z; m[2][3] = 0.0;
105  m[3][0] = 0.0 ; m[3][1] = 0.0 ; m[3][2] = 0.0 ; 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  */
118 void 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,
149  vp->vrp.x - vp->cop.x,
150  vp->vrp.y - vp->cop.y,
151  vp->vrp.z - vp->cop.z);
152  norm_vector (&dop);
153  SET_COORD3(cop,dop.x,dop.y,dop.z);
154  point_matrix (&doprim, &cop, m);
155  ident_matrix (m);
156  m[2][0] = - doprim.x / doprim.z;
157  m[2][1] = - doprim.y / doprim.z;
158  postmult_matrix (wc, m);
159  /*
160  * 6 : Translation et Mise a l'echelle de la pyramide.
161  * Remarque : contrairement a la reference qui donne
162  * 0 < x < 1, 0 < y < 1, 0 < z < 1
163  * je prefere, afin de rester coherent avec la projection perspective,
164  * -1 < x < 1, -1 < y < 1, 0 < z < 1 (w = 1)
165  */
166  SET_COORD3(v,
167  (float)(-(vp->vwd.umax + vp->vwd.umin) / 2.0),
168  (float)(-(vp->vwd.vmax + vp->vwd.vmin) / 2.0),
169  (float)(-vp->depth.front));
170  posttrans_matrix (wc, &v);
171  SET_COORD3(v,
172  (float)(2.0 / (vp->vwd.umax - vp->vwd.umin)),
173  (float)(2.0 / (vp->vwd.vmax - vp->vwd.vmin)),
174  (float)(1.0 / (vp->depth.back - vp->depth.front)));
175  postscale_matrix (wc, &v);
176 }
177 
178 /*
179  * La procedure "set_perspective" iniatilise la matrice de projection
180  * perspective "wc" par les parametres de visualisation "vp".
181  * Pour plus de renseignements :
182  * "Fundamentals of Interactive Computer Graphics"
183  * J.D. FOLEY, A. VAN DAM, Addison-Wesley. 1982, pp 290-302.
184  * Entree :
185  * vp Parametres de visualisation.
186  * wc Matrice a initialiser.
187  */
188 void set_perspective (View_parameters *vp, Matrix wc)
189 {
190  Matrix m = IDENTITY_MATRIX;
191  Point4f vrprim, cw;
192  float zmin;
193  Vector v;
194 
195  /*
196  * 1 : Translation du centre de projection COP a l'origine.
197  */
198  SET_COORD3(v,- vp->cop.x, - vp->cop.y, - vp->cop.z);
199  Translate_to_Matrix (&v, wc);
200  /*
201  * 2 : Rotation pour rendre VPN parallele a l'axe des Z negatifs.
202  * 3 : Rotation pour rendre la projection de VUP sur le plan de
203  * projection parallele a l'axe Y.
204  */
205  set_zy (m, &vp->vpn, &vp->vup);
206  postmult_matrix (wc, m);
207  /*
208  * 4 : Passer d'un repere droit (absolu) a un repere gauche (vision).
209  */
210  postleft_matrix (wc, 'z');
211  /*
212  * 5 : Alignement de l'axe central du volume de vision sur l'axe Z.
213  */
214  point_matrix (&vrprim, &vp->vrp, wc);
215  cw.x = (float)(vrprim.x + (vp->vwd.umin + vp->vwd.umax) / 2.0);
216  cw.y = (float)(vrprim.y + (vp->vwd.vmin + vp->vwd.vmax) / 2.0);
217  cw.z = (float)(vrprim.z);
218  ident_matrix (m);
219  m[2][0] = - cw.x / cw.z;
220  m[2][1] = - cw.y / cw.z;
221  postmult_matrix (wc, m);
222  /*
223  * 6 : Mise a l'echelle de la pyramide.
224  */
225  SET_COORD3(v,
226  (float)((2.0*vrprim.z)/((vp->vwd.umax-vp->vwd.umin)*(vrprim.z+vp->depth.back))),
227  (float)((2.0*vrprim.z)/((vp->vwd.vmax-vp->vwd.vmin)*(vrprim.z+vp->depth.back))),
228  (float)( 1.0/(vrprim.z+vp->depth.back)));
229  postscale_matrix (wc, &v);
230  /*
231  * 7 : Transformation perspective.
232  */
233  zmin = (vrprim.z + vp->depth.front) / (vrprim.z + vp->depth.back);
234  ident_matrix (m);
235  m[2][2] = (float)(1.0 / (1.0 - zmin)); m[2][3] = 1.0;
236  m[3][2] = (float)(- zmin / (1.0 - zmin)); m[3][3] = 0.0;
237  postmult_matrix (wc, m);
238 }
239 
240 #endif