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