htransform.c
Go to the documentation of this file.
1 #include "htransform.h"
2 
3 #include "error.h"
4 #include "basic_algebra.h"
5 
6 #include <math.h>
7 #include <string.h>
8 #include <basic_algebra.h>
9 
20 /*THTransforms[i][j] -> row i column j */
21 
22 
28 const THTransform matrix_identity={{1.0, 0.0, 0.0, 0.0},
29  {0.0, 1.0, 0.0, 0.0},
30  {0.0, 0.0, 1.0, 0.0},
31  {0.0, 0.0, 0.0, 1.0}};
32 
38 const THTransform matrix_zero={{0.0, 0.0, 0.0, 0.0},
39  {0.0, 0.0, 0.0, 0.0},
40  {0.0, 0.0, 0.0, 0.0},
41  {0.0, 0.0, 0.0, 0.0}};
42 
43 #ifdef _CBLAS
44 
52  #define MATRIX_INT_COPY(td,to) cblas_dcopy(16,(double*)(to),1,(double*)(td),1)
53 #else
54 
62  #define MATRIX_INT_COPY(td,to) memcpy((td),(to),sizeof(THTransform))
63 #endif
64 
65 
66 /*
67  * Returns the identity matrix in t
68  */
69 void HTransformIdentity(THTransform *t /*Resulting matrix*/
70  )
71 {
72  MATRIX_INT_COPY((*t),&matrix_identity);
73 }
74 
76 {
77  MATRIX_INT_COPY((*t),&matrix_zero);
78 }
79 
80 /*
81 * Copies to in td
82 */
83 void HTransformCopy(THTransform *t_dst, /*HTransform where to copy the original*/
84  THTransform *t_src /*Original matrix*/
85  )
86 {
87  MATRIX_INT_COPY((*t_dst),(*t_src));
88 }
89 
90 /* Identify the identity matrix*/
92 {
93  return(Distance(16,(double *)t,(double *)matrix_identity)<16*ZERO);
94 }
95 
96 /* Identify the zero matrix*/
98 {
99  return(Distance(16,(double *)t,(double *)matrix_zero)<16*ZERO);
100 }
101 
103 {
104  return((fabs((*t)[AXIS_X][AXIS_X]-1)<ZERO)&&
105  (fabs((*t)[AXIS_Y][AXIS_Y]-1)<ZERO)&&
106  (fabs((*t)[AXIS_Z][AXIS_Z]-1)<ZERO));
107 }
108 
109 /*
110  * Returns a matrix that produces a translation of size tx along axis x.
111  */
112 void HTransformTx(double tx, /*Translation parameter*/
113  THTransform *t /*Resulting matrix*/
114  )
115 {
116  MATRIX_INT_COPY(*t,&matrix_identity);
117  (*t)[AXIS_X][AXIS_H]=tx;
118 }
119 
120 /*
121  * Returns a matrix that produces a translation of size ty along axis y.
122  */
123 void HTransformTy(double ty, /*Translation parameter*/
124  THTransform *t /*Resulting matrix*/
125  )
126 {
127  MATRIX_INT_COPY(*t,&matrix_identity);
128  (*t)[AXIS_Y][AXIS_H]=ty;
129 }
130 
131 /*
132  * Returns a matrix that produces a translation of size tz along axis z.
133  */
134 void HTransformTz(double tz, /*Translation parameter*/
135  THTransform *t /*Resulting matrix*/
136  )
137 {
138  MATRIX_INT_COPY(*t,&matrix_identity);
139  (*t)[AXIS_Z][AXIS_H]=tz;
140 }
141 
142 /*
143  * Returns a matrix that produces a translation of size tx along axis x,
144  * of size ty along axis y, and along tz along axis z.
145  */
146 void HTransformTxyz(double tx, /*Translation parameter along the x axis*/
147  double ty, /*Translation parameter along the y axis*/
148  double tz, /*Translation parameter along the z axis*/
149  THTransform *t /*Resulting matrix*/
150  )
151 {
152  MATRIX_INT_COPY(*t,&matrix_identity);
153  (*t)[AXIS_X][AXIS_H]=tx;
154  (*t)[AXIS_Y][AXIS_H]=ty;
155  (*t)[AXIS_Z][AXIS_H]=tz;
156 }
157 
158 /*
159  * Returns a matrix that produces a rotation of size rx around axis x.
160  */
161 void HTransformRx(double rx, /*Rotation parameter*/
162  THTransform *t /*Resulting matrix*/
163  )
164 {
165  double s,c;
166 
167  s=sin(rx);
168  c=cos(rx);
169 
170  MATRIX_INT_COPY(*t,&matrix_identity);
171  (*t)[AXIS_Y][AXIS_Y]=c; (*t)[AXIS_Y][AXIS_Z]=-s;
172  (*t)[AXIS_Z][AXIS_Y]=s; (*t)[AXIS_Z][AXIS_Z]= c;
173 }
174 
175 /*
176  * Returns a matrix that produces a rotation of size rt around axis y.
177  */
178 void HTransformRy(double ry, /*Rotation parameter*/
179  THTransform *t /*Resulting matrix*/
180  )
181 {
182  double s,c;
183 
184  s=sin(ry);
185  c=cos(ry);
186 
187  MATRIX_INT_COPY(*t,&matrix_identity);
188  (*t)[AXIS_X][AXIS_X]= c; (*t)[AXIS_X][AXIS_Z]=s;
189  (*t)[AXIS_Z][AXIS_X]=-s; (*t)[AXIS_Z][AXIS_Z]=c;
190 }
191 
192 /*
193  * Returns a matrix that produces a rotation of size rz around axis z.
194  */
195 void HTransformRz(double rz, /*Rotation parameter*/
196  THTransform *t /*Resulting matrix*/
197  )
198 {
199  double s,c;
200 
201  s=sin(rz);
202  c=cos(rz);
203 
204  MATRIX_INT_COPY(*t,&matrix_identity);
205  (*t)[AXIS_X][AXIS_X]=c; (*t)[AXIS_X][AXIS_Y]=-s;
206  (*t)[AXIS_Y][AXIS_X]=s; (*t)[AXIS_Y][AXIS_Y]=c;
207 }
208 
209 /*
210  * Init a rotation matrix around the x axis from a sinus and cosinus value
211  */
212 void HTransformRx2(double s,double c,THTransform *t)
213 {
214  MATRIX_INT_COPY(*t,&matrix_identity);
215  (*t)[AXIS_Y][AXIS_Y]=c; (*t)[AXIS_Y][AXIS_Z]=-s;
216  (*t)[AXIS_Z][AXIS_Y]=s; (*t)[AXIS_Z][AXIS_Z]= c;
217 }
218 
219 /*
220  * Init a rotation matrix around the y axis from a sinus and cosinus value
221  */
222 void HTransformRy2(double s,double c,THTransform *t)
223 {
224  MATRIX_INT_COPY(*t,&matrix_identity);
225  (*t)[AXIS_X][AXIS_X]= c; (*t)[AXIS_X][AXIS_Z]=s;
226  (*t)[AXIS_Z][AXIS_X]=-s; (*t)[AXIS_Z][AXIS_Z]=c;
227 }
228 
229 /*
230  * Init a rotation matrix around the z axis from a sinus and cosinus value
231  */
232 void HTransformRz2(double s,double c,THTransform *t)
233 {
234  MATRIX_INT_COPY(*t,&matrix_identity);
235  (*t)[AXIS_X][AXIS_X]=c; (*t)[AXIS_X][AXIS_Y]=-s;
236  (*t)[AXIS_Y][AXIS_X]=s; (*t)[AXIS_Y][AXIS_Y]=c;
237 }
238 
239 void HTransformScale(double s, /*Scale factor*/
240  THTransform *t /*Resulting matrix*/
241  )
242 {
243  MATRIX_INT_COPY(*t,&matrix_identity);
244  (*t)[AXIS_X][AXIS_X]=s;
245  (*t)[AXIS_Y][AXIS_Y]=s;
246  (*t)[AXIS_Z][AXIS_Z]=s;
247 }
248 
249 void HTransformScaleX(double s, /*Scale factor*/
250  THTransform *t /*Resulting matrix*/
251  )
252 {
253  MATRIX_INT_COPY(*t,&matrix_identity);
254  (*t)[AXIS_X][AXIS_X]=s;
255 }
256 
257 void HTransformScaleY(double s, /*Scale factor*/
258  THTransform *t /*Resulting matrix*/
259  )
260 {
261  MATRIX_INT_COPY(*t,&matrix_identity);
262  (*t)[AXIS_Y][AXIS_Y]=s;
263 }
264 
265 void HTransformScaleZ(double s, /*Scale factor*/
266  THTransform *t /*Resulting matrix*/
267  )
268 {
269  MATRIX_INT_COPY(*t,&matrix_identity);
270  (*t)[AXIS_Z][AXIS_Z]=s;
271 }
272 
273 /*
274  * Returns a transformation matrix of size v along/arond the desired
275  * axis. There are six predefined constants (TX,TY,TZ,RX,RY,RX) to
276  * facilitate the use of this function.
277  */
278 void HTransformCreate(unsigned int dof_r3, /*DOF*/
279  double v, /*displacement along/around the DOF*/
280  THTransform *t /*Resulting matrix*/
281  )
282 {
283  switch (dof_r3)
284  {
285  case TX:
286  HTransformTx(v,t);
287  break;
288  case TY:
289  HTransformTy(v,t);
290  break;
291  case TZ:
292  HTransformTz(v,t);
293  break;
294  case RX:
295  HTransformRx(v,t);
296  break;
297  case RY:
298  HTransformRy(v,t);
299  break;
300  case RZ:
301  HTransformRz(v,t);
302  break;
303  default:
304  Error("Wrong type of transform in HTransformCreate");
305  }
306 }
307 
308 /*
309  * Modifies the value of the element of row i and column j of the matrix t and
310  * sets it to v.
311 */
312 inline void HTransformSetElement(unsigned int i, /*row*/
313  unsigned int j, /*column*/
314  double v, /*New value*/
315  THTransform *t /*HTransform to be modified*/
316  )
317 {
318  #if (_DEBUG>0)
319  if ((i>AXIS_H)||(j>AXIS_H))
320  Error("Element out of range in HTransformSetElement");
321  #endif
322  (*t)[i][j]=v;
323 }
324 
325 /*
326  * Returns the element of row i and column j of matrix t
327  */
328 
329 inline double HTransformGetElement(unsigned int i,/*row*/
330  unsigned int j,/*column*/
331  THTransform *t /*HTransform to be queried*/
332  )
333 {
334  #if (_DEBUG>0)
335  if ((i>AXIS_H)||(j>AXIS_H))
336  Error("Element out of range in HTransformGetElement");
337  #endif
338  return((*t)[i][j]);
339 }
340 
341 void HTransformFromVectors(double *x,double *y,double *z,double *h,THTransform *t)
342 {
343  unsigned int i;
344 
345  for(i=0;i<3;i++) /* row */
346  {
347  (*t)[i][AXIS_X]=x[i];
348  (*t)[i][AXIS_Y]=y[i];
349  (*t)[i][AXIS_Z]=z[i];
350  (*t)[i][AXIS_H]=h[i];
351 
352  (*t)[AXIS_H][i]=0.0; /* Last row is 0 */
353  }
354  (*t)[AXIS_H][AXIS_H]=1.0;
355 }
356 
358 {
359  #ifdef _CBLAS
360  cblas_dcopy(4,&((*t)[0][0]),4,&(m[ 0]),1);
361  cblas_dcopy(4,&((*t)[0][1]),4,&(m[ 4]),1);
362  cblas_dcopy(4,&((*t)[0][2]),4,&(m[ 8]),1);
363  cblas_dcopy(4,&((*t)[0][3]),4,&(m[12]),1);
364  #else
365  unsigned int i,j;
366  double *ptr;
367 
368  ptr=m;
369  for(j=0;j<=AXIS_H;j++)
370  {
371  for(i=0;i<=AXIS_H;i++,ptr++)
372  {
373  *ptr=(*t)[i][j];
374  }
375  }
376  #endif
377 }
378 
380 {
381  #ifdef _CBLAS
382  cblas_dcopy(4,&(m[ 0]),1,&((*t)[0][0]),4);
383  cblas_dcopy(4,&(m[ 4]),1,&((*t)[0][1]),4);
384  cblas_dcopy(4,&(m[ 8]),1,&((*t)[0][2]),4);
385  cblas_dcopy(4,&(m[12]),1,&((*t)[0][3]),4);
386  #else
387  unsigned int i,j;
388  double *ptr;
389 
390  ptr=m;
391  for(j=0;j<=AXIS_H;j++)
392  {
393  for(i=0;i<=AXIS_H;i++,ptr++)
394  {
395  (*t)[i][j]=*ptr;
396  }
397  }
398  #endif
399 }
400 
401 /*
402  * Makes the product of two matrixes and returns it on t3.
403  * t3=t1*t2
404  * The procedure is safe enough and enables t3 no to be
405  * different from t1 or t2.
406  *
407  * This is a CRITICAL function and, thus, we try to accelerate it
408  * as much as possible.
409  */
410 CBLAS_INLINE void HTransformProduct(THTransform *t1, /*First matrix*/
411  THTransform *t2, /*Second matrix*/
412  THTransform *t3 /*Resulting matrix*/
413  )
414 {
415  THTransform t4;
416  #ifdef _CBLAS
417  cblas_dgemm(CblasRowMajor,CblasNoTrans,CblasNoTrans,
418  4,4,4,1.0,(double*)t1,4,(double*)t2,4,0.0,(double*)t4,4);
419  #else
420  unsigned int i,j,k;
421 
422  for(i=0;i<(DIM_SP+1);i++)
423  {
424  for(j=0;j<(DIM_SP+1);j++)
425  {
426  t4[i][j]=0.0;
427  for(k=0;k<(DIM_SP+1);k++)
428  {
429  t4[i][j]+=(*t1)[i][k]*(*t2)[k][j];
430  }
431  }
432  }
433  #endif
434  MATRIX_INT_COPY(*t3,&t4);
435 }
436 
437 /*
438  * Makes the addition of two matrixes and returns it on t3.
439  * t3=t1+t2
440  * The procedure is safe enough and enables t3 no to be
441  * different from t1 or t2.
442  */
443 CBLAS_INLINE void HTransformAdd(THTransform *t1, /*First matrix*/
444  THTransform *t2, /*Second matrix*/
445  THTransform *t3 /*Resulting matrix*/
446  )
447 {
448  THTransform t4;
449  #ifdef _CBLAS
450  MATRIX_INT_COPY(&t4,t2);
451  cblas_daxpy(16,1.0,(double*)t1,1,(double*)&t4,1);
452  #else
453  unsigned int i,j;
454 
455  for(i=0;i<(DIM_SP+1);i++)
456  {
457  for(j=0;j<(DIM_SP+1);j++)
458  {
459  t4[i][j]=(*t1)[i][j]+(*t2)[i][j];
460  }
461  }
462  #endif
463  MATRIX_INT_COPY(*t3,&t4);
464 }
465 
466 /*
467  * Makes the substraction of two matrixes and returns it on t3.
468  * t3=t1-t2
469  * The procedure is safe enough and enables t3 no to be
470  * different from t1 or t2.
471  */
472 CBLAS_INLINE void HTransformSubstract(THTransform *t1, /*First matrix*/
473  THTransform *t2, /*Second matrix*/
474  THTransform *t3 /*Resulting matrix*/
475  )
476 {
477  THTransform t4;
478  #ifdef _CBLAS
479  MATRIX_INT_COPY(&t4,t1);
480  cblas_daxpy(16,-1.0,(double*)t2,1,(double*)&t4,1);
481  #else
482  unsigned int i,j;
483 
484  for(i=0;i<(DIM_SP+1);i++)
485  {
486  for(j=0;j<(DIM_SP+1);j++)
487  {
488  t4[i][j]=(*t1)[i][j]-(*t2)[i][j];
489  }
490  }
491  #endif
492  MATRIX_INT_COPY(*t3,&t4);
493 }
494 
495 /*
496  * Invert t and returns the results on ti.
497  * Description of the inversion method:
498  * t=t_trans*t_rot
499  * t^-1=t_rot^-1*t_trans^-1
500  * t_rot^-1=t_rot transposed
501  * t_trans^-1=-t_trans
502  */
503 void HTransformInverse(THTransform *t, /*Input matrix*/
504  THTransform *ti /*Resulting matrix (inverse of the input one)*/
505  )
506 {
507  THTransform t_trans;
508  THTransform t_rot;
509  unsigned int i,j;
510 
511  MATRIX_INT_COPY(&t_trans,&matrix_identity);
512  MATRIX_INT_COPY(&t_rot,&matrix_identity);
513 
514  /* invert the translation */
515  t_trans[AXIS_X][AXIS_H]=-(*t)[AXIS_X][AXIS_H];
516  t_trans[AXIS_Y][AXIS_H]=-(*t)[AXIS_Y][AXIS_H];
517  t_trans[AXIS_Z][AXIS_H]=-(*t)[AXIS_Z][AXIS_H];
518 
519  /* invert (transpose) the rotation */
520  for(i=0;i<AXIS_H;i++)
521  {
522  for(j=0;j<AXIS_H;j++)
523  t_rot[i][j]=(*t)[j][i];
524  }
525 
526  HTransformProduct(&t_rot,&t_trans,ti);
527 }
528 
530 {
531  THTransform t_new;
532  double c,n;
533  unsigned int i;
534 
535  MATRIX_INT_COPY(&t_new,&matrix_identity);
536 
537  /*normalize the first vector*/
538  n=0.0;
539  for(i=0;i<3;i++)
540  n+=((*t)[i][0]*(*t)[i][0]);
541  n=sqrt(n);
542  for(i=0;i<3;i++)
543  t_new[i][0]=(*t)[i][0]/n;
544 
545  /*substract from the second vector, the projection of the
546  second vector onto the first one (i.e., keep an the part of the
547  second vector that is orthononal to the first one). */
548  c=0.0; /*cosinus between the two vectors*/
549  for(i=0;i<3;i++)
550  c+=(t_new[i][0]*(*t)[i][1]);
551  for(i=0;i<3;i++)
552  t_new[i][1]=(*t)[i][1]-c*t_new[i][0];
553 
554  /*normalize the second vector*/
555  n=0.0;
556  for(i=0;i<3;i++)
557  n+=(t_new[i][1]*t_new[i][1]);
558  n=sqrt(n);
559  for(i=0;i<3;i++)
560  t_new[i][1]=t_new[i][1]/n;
561 
562  /*The third vector is the cross product of the two first*/
563  t_new[0][2]= t_new[1][0]*t_new[2][1]-t_new[1][1]*t_new[2][0];
564  t_new[1][2]=-t_new[0][0]*t_new[2][1]+t_new[0][1]*t_new[2][0];
565  t_new[2][2]= t_new[0][0]*t_new[1][1]-t_new[0][1]*t_new[1][0];
566 
567  /*The translation is just copied*/
568  for(i=0;i<3;i++)
569  t_new[i][AXIS_H]=(*t)[i][AXIS_H];
570 
571  MATRIX_INT_COPY(*ta,&t_new);
572 }
573 
574 void HTransformX2Vect(double sy,double sz,double *p1,double *p2,THTransform *t)
575 {
576  double x,y,z,l,theta,phi,h;
577  THTransform s,r1,r2;
578 
579  x=p2[0]-p1[0];
580  y=p2[1]-p1[1];
581  z=p2[2]-p1[2];
582 
583  l=sqrt(x*x+y*y+z*z);
584 
585  if (l<1e-6)
586  Error("Too small vector in HTransformX2Vect");
587 
588  h=sqrt(x*x+y*y);
589  if (h<1e-3)
590  {
591  /* A vector along the z axis */
592  theta=0;
593  if (z>0)
594  phi=-M_PI_2; /* -pi/2 */
595  else
596  phi= M_PI_2; /* +pi/2 */
597  }
598  else
599  {
600  theta=atan2(y,x); /*rotation in z*/
601  phi=-atan2(z,h); /*rotation in y*/
602  }
603 
604  /*Scale matrix*/
605  HTransformIdentity(&s);
606  HTransformSetElement(0,0,l,&s);
607  HTransformSetElement(1,1,sy,&s);
608  HTransformSetElement(2,2,sz,&s);
609 
610  /*Rotation around Y*/
611  HTransformRy(phi,&r1);
612 
613  /*Rotation around Z*/
614  HTransformRz(theta,&r2);
615 
616  /*translation to the origin*/
617  HTransformTxyz(p1[0],p1[1],p1[2],t);
618 
619  /*accumulate the transform from last to first*/
620  HTransformProduct(t,&r2,t);
621  HTransformProduct(t,&r1,t);
622  HTransformProduct(t,&s,t);
623 }
624 
625 void HTransformYawPitchRoll(double a,double b,double c,THTransform *t)
626 {
627  /*Rz(a)Ry(b)Rx(c)*/
628 
629  HTransformRz(a,t);
630  HTransformAcumRot(RY,sin(b),cos(b),t);
631  HTransformAcumRot(RX,sin(c),cos(c),t);
632 }
633 
634 void GetYawPitchRoll(double *a,double *b,double *c,THTransform *t)
635 {
636  double r11,r21,r31;
637 
638  /* Taken from http://planning.cs.uiuc.edu/node103.html */
639  r11=(*t)[AXIS_X][AXIS_X];
640  r21=(*t)[AXIS_Y][AXIS_X];
641  r31=(*t)[AXIS_Z][AXIS_X];
642 
643  if ((r11==0.0)&&(r21==0.0))
644  {
645  double r12,r22;
646 
647  /* Treat the singular case. Several solutions
648  are possible for this case. Just pick one. */
649  r12=(*t)[AXIS_X][AXIS_Y];
650  r22=(*t)[AXIS_Y][AXIS_Y];
651 
652  *c=0.0;
653  *b=(r31>0?-M_PI_2:M_PI_2);
654  *a=-atan2(r12,r22);
655  }
656  else
657  {
658  double r32,r33;
659 
660  r32=(*t)[AXIS_Z][AXIS_Y];
661  r33=(*t)[AXIS_Z][AXIS_Z];
662 
663  *a=atan2(r21,r11);
664  *b=atan2(-r31,sqrt(r32*r32+r33*r33));
665  *c=atan2(r32,r33);
666  }
667 }
668 
669 /*
670  * Returns in tt the transposed matrix of t.
671 */
672 void HTransformTranspose(THTransform *t, /*Input matrix*/
673  THTransform *tt /*Resulting matrix (Transposed of the input one)*/
674  )
675 {
676  THTransform t4;
677  unsigned int i,j;
678 
679  for(i=0;i<(DIM_SP+1);i++)
680  {
681  for(j=0;j<(DIM_SP+1);j++)
682  t4[i][j]=(*t)[j][i];
683  }
684  MATRIX_INT_COPY(*tt,&t4);
685 }
686 
687 /*
688  * Returns in t the result of multiplying t by a translation matrix with
689  * parameters tx, ty, tz.
690  * t=t*HTransformTxyz(tx,ty,tz)
691  *
692  * Actually HTransformTxyz is not used and the product is done in a very efficient way.
693  * This functions allows sequences of transformations to be concatened very fast.
694  */
695 CBLAS_INLINE void HTransformAcumTrans(double tx, /*Translation along the x axis*/
696  double ty, /*Translation along the y axis*/
697  double tz, /*Translation along the z axis*/
698  THTransform *t /*Input and resulting matrix after the accumulation of the translation*/
699  )
700 {
701  unsigned int i;
702 
703  for(i=0;i<AXIS_H;i++)
704  (*t)[i][AXIS_H]=(*t)[i][AXIS_X]*tx+(*t)[i][AXIS_Y]*ty+(*t)[i][AXIS_Z]*tz+(*t)[i][AXIS_H];
705 }
706 
707 /*
708  * The same as HTransformAcumTrans but with the input different from the output
709  */
710 CBLAS_INLINE void HTransformAcumTrans2(THTransform *t_in, /*The input matrix*/
711  double tx, /*Translation along the x axis*/
712  double ty, /*Translation along the y axis*/
713  double tz, /*Translation along the z axis*/
714  THTransform *t /*Resulting matrix after the accumulation of the translation*/
715  )
716 {
717  if (t!=t_in)
718  MATRIX_INT_COPY(t,t_in);
719  HTransformAcumTrans(tx,ty,tz,t);
720 }
721 
722 /*
723  * Returns in t the result of multiplying t by a rotations matrix for and angle
724  * with sinus s and cosinus c around the axis indicated by the parameter type (RX,RY,RZ)
725  * t=t*HTransformCreate(type,atan2(s,c))
726  */
727 CBLAS_INLINE void HTransformAcumRot(unsigned int type, /*Type of rotation matrix (RX,RY,RZ)*/
728  double s, /*value of the sinus of the angle to be rotated*/
729  double c, /*value of the cosinus of the angle to be rotated*/
730  THTransform *t /*Input and resulting matrix after the accumulation of the translation*/
731  )
732 {
733  unsigned int i;
734  double aux;
735 
736  switch(type)
737  {
738  case RX:
739  for(i=0;i<AXIS_H;i++)
740  {
741  aux=(*t)[i][AXIS_Y];
742  (*t)[i][AXIS_Y]= aux*c+(*t)[i][AXIS_Z]*s;
743  (*t)[i][AXIS_Z]=-aux*s+(*t)[i][AXIS_Z]*c;
744  }
745  break;
746  case RY:
747  for(i=0;i<AXIS_H;i++)
748  {
749  aux=(*t)[i][AXIS_X];
750  (*t)[i][AXIS_X]=aux*c-(*t)[i][AXIS_Z]*s;
751  (*t)[i][AXIS_Z]=aux*s+(*t)[i][AXIS_Z]*c;
752  }
753  break;
754  case RZ:
755  for(i=0;i<AXIS_H;i++)
756  {
757  aux=(*t)[i][AXIS_X];
758  (*t)[i][AXIS_X]= aux*c+(*t)[i][AXIS_Y]*s;
759  (*t)[i][AXIS_Y]=-aux*s+(*t)[i][AXIS_Y]*c;
760  }
761  break;
762  default:
763  Error("Non rotation matrix type in function HTransformAcumRot");
764  break;
765  }
766 }
767 /*
768  * The same as HTransformAcumRot but with the input different from the output
769  */
770 CBLAS_INLINE void HTransformAcumRot2(THTransform *t_in, /*input matrix*/
771  unsigned int type, /*Type of rotation matrix (RX,RY,RZ)*/
772  double s, /*value of the sinus of the angle to be rotated*/
773  double c, /*value of the cosinus of the angle to be rotated*/
774  THTransform *t /*Resulting matrix after the accumulation of the translation*/
775  )
776 {
777  if (t!=t_in)
778  MATRIX_INT_COPY(t,t_in);
779  HTransformAcumRot(type,s,c,t);
780 }
781 
782 void HTransformApply(double *p_in,double *p_out,THTransform *t)
783 {
784  unsigned int i,j;
785  double pAux[3];
786 
787  for(i=0;i<DIM_SP;i++)
788  {
789  pAux[i]=(*t)[i][AXIS_H]; /*The homogeneous term*/
790 
791  for(j=0;j<DIM_SP;j++)
792  pAux[i]+=((*t)[i][j]*p_in[j]);
793  }
794 
795  p_out[0]=pAux[0];
796  p_out[1]=pAux[1];
797  p_out[2]=pAux[2];
798 }
799 
800 
801 void HTransformApplyRot(double *p_in,double *p_out,THTransform *t)
802 {
803  unsigned int i,j;
804  double pAux[3];
805 
806  for(i=0;i<DIM_SP;i++)
807  {
808  pAux[i]=0.0; /*No homogeneous term*/
809 
810  for(j=0;j<DIM_SP;j++)
811  pAux[i]+=((*t)[i][j]*p_in[j]);
812  }
813 
814  p_out[0]=pAux[0];
815  p_out[1]=pAux[1];
816  p_out[2]=pAux[2];
817 }
818 
819 /*
820  * Prints matrix t on file f
821  */
822 void HTransformPrint(FILE *f, /*File*/
823  THTransform *t /*matrix to be printed*/
824  )
825 {
826  unsigned int i,j;
827 
828  for(i=0;i<DIM_SP+1;i++)
829  {
830  for(j=0;j<(DIM_SP+1);j++)
831  {
832  fprintf(f,"%.16f ",(*t)[i][j]);
833  }
834  fprintf(f,"\n");
835  }
836 }
837 
838 /*
839  * Prints the transposed of matrix t on file f.
840  * This is useful to print homogeneous transform in the Geomview way
841  * Geomview uses row vectors. In this way what for column vectors
842  * (the usual ones!) is
843  * A x
844  * becomes
845  * (A x)^t= x^t A^t
846  * This is way we print A^t instead of A.
847  */
848 void HTransformPrintT(FILE *f, /*File*/
849  THTransform *t /*matrix to be transposed and printed*/
850  )
851 {
852  unsigned int i,j;
853 
854  for(i=0;i<(DIM_SP+1);i++)
855  {
856  for(j=0;j<DIM_SP+1;j++)
857  {
858  fprintf(f,"%f ",(*t)[j][i]);
859  }
860  }
861 }
862 
864 {
865  if (HTransformIsIdentity(t))
866  fprintf(f,"ID");
867  else
868  {
869  fprintf(f,"Txyz(%g,%g,%g)",(*t)[AXIS_X][AXIS_H],(*t)[AXIS_Y][AXIS_H],(*t)[AXIS_Z][AXIS_H]);
870  if (!HTransformIsTranslation(t))
871  {
872  double a,b,c;
873 
874  GetYawPitchRoll(&a,&b,&c,t);
875  if (a!=0.0) fprintf(f,"*Rz(%.16f)",a);
876  if (b!=0.0) fprintf(f,"*Ry(%.16f)",b);
877  if (c!=0.0) fprintf(f,"*Rx(%.16f)",c);
878 
879  //fprintf(f,"*Rz(%lf)*Ry(%lf)*Rx(%lf)",a,b,c);
880  }
881  }
882 }
883 
884 /*
885  * Deletes a matrix structure
886  */
887 inline void HTransformDelete(THTransform *t /*HTransform to be deleted*/
888  )
889 {}
#define AXIS_X
One of the dimension of R^3.
Definition: htransform.h:83
const THTransform matrix_zero
A global constant that defines the zero matrix.
Definition: htransform.c:38
void HTransformScaleY(double s, THTransform *t)
Constructor.
Definition: htransform.c:257
void HTransformRz2(double s, double c, THTransform *t)
Constructor.
Definition: htransform.c:232
void HTransformApply(double *p_in, double *p_out, THTransform *t)
Multiply a homogeneous transform and a vector.
Definition: htransform.c:782
void HTransformTxyz(double tx, double ty, double tz, THTransform *t)
Constructor.
Definition: htransform.c:146
void HTransformRx(double rx, THTransform *t)
Constructor.
Definition: htransform.c:161
void HTransformPrettyPrint(FILE *f, THTransform *t)
Prints a homogenoeus transform compactly.
Definition: htransform.c:863
CBLAS_INLINE void HTransformAcumRot2(THTransform *t_in, unsigned int type, double s, double c, THTransform *t)
Computes the result of multiplying a homogeneous transform by a rotation matrix.
Definition: htransform.c:770
void HTransformTz(double tz, THTransform *t)
Constructor.
Definition: htransform.c:134
void HTransformTranspose(THTransform *t, THTransform *tt)
Transpose of a homogeneous transform.
Definition: htransform.c:672
A homgeneous transform in R^3.
#define AXIS_Y
One of the dimension of R^3.
Definition: htransform.h:91
#define RZ
One of the types of homogeneous transforms in R^3.
Definition: htransform.h:75
void HTransformZero(THTransform *t)
Constructor.
Definition: htransform.c:75
CBLAS_INLINE void HTransformAcumTrans2(THTransform *t_in, double tx, double ty, double tz, THTransform *t)
Computes the result of multiplying a homogeneous transform by a translation matrix with parameters tx...
Definition: htransform.c:710
void HTransformApplyRot(double *p_in, double *p_out, THTransform *t)
Multiply the rotation part of the homogeneous transform and a vector.
Definition: htransform.c:801
CBLAS_INLINE void HTransformSubstract(THTransform *t1, THTransform *t2, THTransform *t3)
Substraction of two homogeneous transforms.
Definition: htransform.c:472
CBLAS_INLINE void HTransformAcumTrans(double tx, double ty, double tz, THTransform *t)
Computes the result of multiplying a homogeneous transform by a translation matrix with parameters tx...
Definition: htransform.c:695
#define RY
One of the types of homogeneous transforms in R^3.
Definition: htransform.h:67
CBLAS_INLINE void HTransform2GLMatrix(double *m, THTransform *t)
Defines a GL column-major matrix from a homogeneous transform.
Definition: htransform.c:357
void Error(const char *s)
General error function.
Definition: error.c:80
void HTransformYawPitchRoll(double a, double b, double c, THTransform *t)
Defines a rotation matrix from the yaw, pitch, and roll parameters.
Definition: htransform.c:625
#define MATRIX_INT_COPY(td, to)
A fast way to copy one matrix (to) into another matrix(td)
Definition: htransform.c:62
#define TZ
One of the types of homogeneous transforms in R^3.
Definition: htransform.h:51
#define AXIS_H
The homogeneous dimension in R^3.
Definition: htransform.h:108
CBLAS_INLINE void HTransformProduct(THTransform *t1, THTransform *t2, THTransform *t3)
Product of two homogeneous transforms.
Definition: htransform.c:410
#define ZERO
Floating point operations giving a value below this constant (in absolute value) are considered 0...
Definition: defines.h:37
void HTransformX2Vect(double sy, double sz, double *p1, double *p2, THTransform *t)
Transform a unitary vector along the X axis to a generic vector.
Definition: htransform.c:574
boolean HTransformIsTranslation(THTransform *t)
Identify the translation matrices.
Definition: htransform.c:102
Error and warning functions.
void HTransformScaleZ(double s, THTransform *t)
Constructor.
Definition: htransform.c:265
double HTransformGetElement(unsigned int i, unsigned int j, THTransform *t)
Gets an element in a homogeneous transform.
Definition: htransform.c:329
void HTransformFromVectors(double *x, double *y, double *z, double *h, THTransform *t)
Defines a homogeneous transform from 4 vectors.
Definition: htransform.c:341
#define CBLAS_INLINE
Inline BLAS-based functions.
Definition: basic_algebra.h:48
double Distance(unsigned int s, double *v1, double *v2)
Computes the distance of two points.
void HTransformRz(double rz, THTransform *t)
Constructor.
Definition: htransform.c:195
void HTransformInverse(THTransform *t, THTransform *ti)
Inverse of a homogeneous transform.
Definition: htransform.c:503
#define AXIS_Z
One of the dimension of R^3.
Definition: htransform.h:99
#define TX
One of the types of homogeneous transforms in R^3.
Definition: htransform.h:35
#define M_PI_2
Pi/2.
Definition: defines.h:92
void GetYawPitchRoll(double *a, double *b, double *c, THTransform *t)
Recovers the Euler angles from a rotation matrix.
Definition: htransform.c:634
void HTransformScaleX(double s, THTransform *t)
Constructor.
Definition: htransform.c:249
CBLAS_INLINE void HTransformAdd(THTransform *t1, THTransform *t2, THTransform *t3)
Addition of two homogeneous transforms.
Definition: htransform.c:443
Definition of the THTransform type and the associated functions.
CBLAS_INLINE void HTransformFromGLMatrix(double *m, THTransform *t)
Defines homogeneous transform from a GL matrix.
Definition: htransform.c:379
CBLAS_INLINE void HTransformAcumRot(unsigned int type, double s, double c, THTransform *t)
Computes the result of multiplying a homogeneous transform by a rotation matrix.
Definition: htransform.c:727
#define RX
One of the types of homogeneous transforms in R^3.
Definition: htransform.h:59
void HTransformTx(double tx, THTransform *t)
Constructor.
Definition: htransform.c:112
const THTransform matrix_identity
A global constant that defines the identity matrix.
Definition: htransform.c:28
void HTransformDelete(THTransform *t)
Destructor.
Definition: htransform.c:887
void HTransformSetElement(unsigned int i, unsigned int j, double v, THTransform *t)
Sets an element in a homogeneous transform.
Definition: htransform.c:312
#define DIM_SP
Dimensions of R^3.
Definition: htransform.h:27
void HTransformTy(double ty, THTransform *t)
Constructor.
Definition: htransform.c:123
void HTransformCopy(THTransform *t_dst, THTransform *t_src)
Copy constructor.
Definition: htransform.c:83
void HTransformPrintT(FILE *f, THTransform *t)
Prints the transpose of a homogeneous transform to a file.
Definition: htransform.c:848
void HTransformCreate(unsigned int dof_r3, double v, THTransform *t)
Constructor.
Definition: htransform.c:278
boolean HTransformIsZero(THTransform *t)
Identify the zero matrix.
Definition: htransform.c:97
void HTransformPrint(FILE *f, THTransform *t)
Prints the a homogeneous transform to a file.
Definition: htransform.c:822
void HTransformRy(double ry, THTransform *t)
Constructor.
Definition: htransform.c:178
void HTransformIdentity(THTransform *t)
Constructor.
Definition: htransform.c:69
void HTransformScale(double s, THTransform *t)
Constructor.
Definition: htransform.c:239
void HTransformRy2(double s, double c, THTransform *t)
Constructor.
Definition: htransform.c:222
void HTransformOrthonormalize(THTransform *t, THTransform *ta)
Orthonormalizes the rotation part of a homogenouos transform.
Definition: htransform.c:529
void HTransformRx2(double s, double c, THTransform *t)
Constructor.
Definition: htransform.c:212
#define TY
One of the types of homogeneous transforms in R^3.
Definition: htransform.h:43
boolean HTransformIsIdentity(THTransform *t)
Identify the identity matrix.
Definition: htransform.c:91