ViSP
vpProjection.cpp
1 /****************************************************************************
2  *
3  * $Id: vpProjection.cpp 5284 2015-02-09 14:24:10Z fspindle $
4  *
5 * This file is part of the ViSP software.
6  * Copyright (C) 2005 - 2014 by INRIA. All rights reserved.
7  *
8  * This software is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * ("GPL") version 2 as published by the Free Software Foundation.
11  * See the file LICENSE.txt at the root directory of this source
12  * distribution for additional information about the GNU GPL.
13  *
14  * For using ViSP with software that can not be combined with the GNU
15  * GPL, please contact INRIA about acquiring a ViSP Professional
16  * Edition License.
17  *
18  * See http://www.irisa.fr/lagadic/visp/visp.html for more information.
19  *
20  * This software was developed at:
21  * INRIA Rennes - Bretagne Atlantique
22  * Campus Universitaire de Beaulieu
23  * 35042 Rennes Cedex
24  * France
25  * http://www.irisa.fr/lagadic
26  *
27  * If you have questions regarding the use of this file, please contact
28  * INRIA at visp@inria.fr
29  *
30  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
31  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
32  *
33  * Description:
34  * Le module "projection.c" contient les procedures de calcul
35  * des matrices de projection perspective et parallele.
36  *
37  * Authors:
38  * Jean-Luc CORRE
39  *
40  *****************************************************************************/
41 
42 
43 
44 
45 
46 
47 #include <visp/vpConfig.h>
48 
49 #ifndef DOXYGEN_SHOULD_SKIP_THIS
50 #include <visp/vpMy.h>
51 #include <visp/vpArit.h>
52 #include <visp/vpView.h>
53 #include <stdio.h>
54 #include <math.h>
55 void set_parallel (View_parameters*, Matrix);
56 void set_perspective (View_parameters*, Matrix);
57 
58 
59 
60 /*
61  * La procedure "View_to_Matrix" constuit la matrice homogene de projection
62  * a partir des parametres de la prise de vue.
63  * Entree :
64  * vp Parametres de la prise de vue.
65  * m Matrice homogene a construire.
66  */
67 void View_to_Matrix (View_parameters *vp, Matrix m)
68 {
69  static char proc_name[] = "View_to_Matrix";
70 
71  switch (vp->type) {
72  case PARALLEL :
73  set_parallel (vp, m);
74  break;
75  case PERSPECTIVE :
76  set_perspective (vp, m);
77  break;
78  default :
79  fprintf (stderr, "%s: bad view type\n", proc_name);
80  set_perspective (vp, m);
81  break;
82  }
83 }
84 
85 
86 /*
87  * La procedure "set_zy" initialise la matrice par une composition :
88  * 1 - aligne le premier vecteur sur l'axe Z dans le sens negatif.
89  * 2 - aligne la projection du second vecteur sur l'axe Y.
90  * Entree :
91  * m Matrice a initialiser.
92  * v0 Premier vecteur.
93  * v1 Second vecteur.
94  */
95 static void set_zy (Matrix m, Vector *v0, Vector *v1)
96 {
97  Vector rx, ry, rz;
98 
99  SET_COORD3(rz, - v0->x,- v0->y, - v0->z);
100  CROSS_PRODUCT(rx, *v0, *v1);
101  norm_vector (&rx);
102  norm_vector (&rz);
103  CROSS_PRODUCT (ry,rz,rx); /* ry est norme */
104 
105  m[0][0] = rx.x; m[0][1] = ry.x; m[0][2] = rz.x; m[0][3] = 0.0;
106  m[1][0] = rx.y; m[1][1] = ry.y; m[1][2] = rz.y; m[1][3] = 0.0;
107  m[2][0] = rx.z; m[2][1] = ry.z; m[2][2] = rz.z; m[2][3] = 0.0;
108  m[3][0] = 0.0 ; m[3][1] = 0.0 ; m[3][2] = 0.0 ; m[3][3] = 1.0;
109 }
110 
111 /*
112  * La procedure "set_parallel" iniatilise la matrice de projection
113  * parallel "wc" par les parametres de visualisation "vp".
114  * Pour plus de renseignements :
115  * "Fundamentals of Interactive Computer Graphics"
116  * J.D. FOLEY, A. VAN DAM, Addison-Wesley. 1982, pp 285-290.
117  * Entree :
118  * vp Parametres de visualisation.
119  * wc Matrice a initialiser.
120  */
121 void set_parallel (View_parameters *vp, Matrix wc)
122 {
123  Matrix m = IDENTITY_MATRIX;
124  Point3f cop;
125  Point4f doprim;
126  Vector dop, v;
127 
128  /*
129  * 1 : Translation du point de reference VRP a l'origine.
130  */
131  SET_COORD3(v,- vp->vrp.x, - vp->vrp.y, - vp->vrp.z);
132  Translate_to_Matrix (&v, wc);
133  /*
134  * 2 : Rotation pour rendre VPN parallele a l'axe des Z negatifs.
135  * 3 : Rotation pour rendre la projection de VUP sur le plan de
136  * projection parallele a l'axe Y.
137  */
138  set_zy (m, &vp->vpn, &vp->vup);
139  /*
140  * 4 : Passer d'un repere droit (absolu) a un repere gauche (vision).
141  */
142  postleft_matrix (m, 'z');
143  postmult_matrix (wc, m);
144  /*
145  * 5 : Alignement de l'axe central du volume de vision sur l'axe Z.
146  * COP = DOP = Direction of Projection.
147  * DOPRIM = DOP * R_TRL
148  * Pas de translation dans la matrice R_TRL pour la transformation
149  * du vecteur DOP.
150  */
151  SET_COORD3(dop,
152  vp->vrp.x - vp->cop.x,
153  vp->vrp.y - vp->cop.y,
154  vp->vrp.z - vp->cop.z);
155  norm_vector (&dop);
156  SET_COORD3(cop,dop.x,dop.y,dop.z);
157  point_matrix (&doprim, &cop, m);
158  ident_matrix (m);
159  m[2][0] = - doprim.x / doprim.z;
160  m[2][1] = - doprim.y / doprim.z;
161  postmult_matrix (wc, m);
162  /*
163  * 6 : Translation et Mise a l'echelle de la pyramide.
164  * Remarque : contrairement a la reference qui donne
165  * 0 < x < 1, 0 < y < 1, 0 < z < 1
166  * je prefere, afin de rester coherent avec la projection perspective,
167  * -1 < x < 1, -1 < y < 1, 0 < z < 1 (w = 1)
168  */
169  SET_COORD3(v,
170  (float)(-(vp->vwd.umax + vp->vwd.umin) / 2.0),
171  (float)(-(vp->vwd.vmax + vp->vwd.vmin) / 2.0),
172  (float)(-vp->depth.front));
173  posttrans_matrix (wc, &v);
174  SET_COORD3(v,
175  (float)(2.0 / (vp->vwd.umax - vp->vwd.umin)),
176  (float)(2.0 / (vp->vwd.vmax - vp->vwd.vmin)),
177  (float)(1.0 / (vp->depth.back - vp->depth.front)));
178  postscale_matrix (wc, &v);
179 }
180 
181 /*
182  * La procedure "set_perspective" iniatilise la matrice de projection
183  * perspective "wc" par les parametres de visualisation "vp".
184  * Pour plus de renseignements :
185  * "Fundamentals of Interactive Computer Graphics"
186  * J.D. FOLEY, A. VAN DAM, Addison-Wesley. 1982, pp 290-302.
187  * Entree :
188  * vp Parametres de visualisation.
189  * wc Matrice a initialiser.
190  */
191 void set_perspective (View_parameters *vp, Matrix wc)
192 {
193  Matrix m = IDENTITY_MATRIX;
194  Point4f vrprim, cw;
195  float zmin;
196  Vector v;
197 
198  /*
199  * 1 : Translation du centre de projection COP a l'origine.
200  */
201  SET_COORD3(v,- vp->cop.x, - vp->cop.y, - vp->cop.z);
202  Translate_to_Matrix (&v, wc);
203  /*
204  * 2 : Rotation pour rendre VPN parallele a l'axe des Z negatifs.
205  * 3 : Rotation pour rendre la projection de VUP sur le plan de
206  * projection parallele a l'axe Y.
207  */
208  set_zy (m, &vp->vpn, &vp->vup);
209  postmult_matrix (wc, m);
210  /*
211  * 4 : Passer d'un repere droit (absolu) a un repere gauche (vision).
212  */
213  postleft_matrix (wc, 'z');
214  /*
215  * 5 : Alignement de l'axe central du volume de vision sur l'axe Z.
216  */
217  point_matrix (&vrprim, &vp->vrp, wc);
218  cw.x = (float)(vrprim.x + (vp->vwd.umin + vp->vwd.umax) / 2.0);
219  cw.y = (float)(vrprim.y + (vp->vwd.vmin + vp->vwd.vmax) / 2.0);
220  cw.z = (float)(vrprim.z);
221  ident_matrix (m);
222  m[2][0] = - cw.x / cw.z;
223  m[2][1] = - cw.y / cw.z;
224  postmult_matrix (wc, m);
225  /*
226  * 6 : Mise a l'echelle de la pyramide.
227  */
228  SET_COORD3(v,
229  (float)((2.0*vrprim.z)/((vp->vwd.umax-vp->vwd.umin)*(vrprim.z+vp->depth.back))),
230  (float)((2.0*vrprim.z)/((vp->vwd.vmax-vp->vwd.vmin)*(vrprim.z+vp->depth.back))),
231  (float)( 1.0/(vrprim.z+vp->depth.back)));
232  postscale_matrix (wc, &v);
233  /*
234  * 7 : Transformation perspective.
235  */
236  zmin = (vrprim.z + vp->depth.front) / (vrprim.z + vp->depth.back);
237  ident_matrix (m);
238  m[2][2] = (float)(1.0 / (1.0 - zmin)); m[2][3] = 1.0;
239  m[3][2] = (float)(- zmin / (1.0 - zmin)); m[3][3] = 0.0;
240  postmult_matrix (wc, m);
241 }
242 
243 #endif