trans_seq.c
Go to the documentation of this file.
1 #include "trans_seq.h"
2 
3 #include "geom.h"
4 #include "basic_algebra.h"
5 
6 #include <math.h>
7 #include <string.h>
8 
17 /*************************************************************************/
18 /*************************************************************************/
19 /*************************************************************************/
20 
22 {
23  t->t=CT_TRANS;
24  t->s=1;
25  t->u=NO_UINT;
26  t->v=NO_UINT;
27  t->val=0.0;
28  NEW(t->ct,1,THTransform);
29  HTransformCopy(t->ct,ct);
30  t->vect=NULL;
31  t->p=NULL;
32 }
33 
34 void InitVarTrans(unsigned int tp,int s,unsigned int v,TTrans *t)
35 {
36  if ((tp==CT_TRANS)||(IS_PATCH_TRANS(tp))||(tp==TV))
37  Error("InitVarTrans should not be used for CT_TRANS, TV, or PA transforms");
38  t->t=tp;
39  t->s=s;
40  t->v=v;
41  t->u=NO_UINT;
42  t->val=0.0;
43  t->ct=NULL;
44  t->vect=NULL;
45  t->p=NULL;
46 }
47 
48 void InitTVTrans(int s,unsigned int v,double *vect,TTrans *t)
49 {
50  t->t=TV;
51  t->s=s;
52  t->v=v;
53  t->u=NO_UINT;
54  t->val=0.0;
55  t->ct=NULL;
56  NEW(t->vect,3,double);
57  memcpy(t->vect,vect,3*sizeof(double));
58  t->p=NULL;
59 }
60 
61 void InitPatchTrans(unsigned int tp,int s,unsigned int u,unsigned int v,
62  double **p,TTrans *t)
63 {
64  unsigned int i;
65 
66  if (!IS_PATCH_TRANS(tp))
67  Error("Using InitPatchTrans to define a non-PA transform");
68 
69  if (u==v)
70  Error("Repeated parameter in InitPatchTrans");
71 
72  t->t=tp;
73  t->s=s;
74  t->v=v;
75  t->u=u;
76  t->val=0.0;
77  t->ct=NULL;
78  t->vect=NULL;
79  NEW(t->p,7,double*);
80  for(i=0;i<7;i++)
81  { NEW(t->p[i],3,double); }
82  if (tp==PA)
83  {
84  memcpy(t->p[0],p[0],3*sizeof(double)); /* (p_0) t->p_0=p_0 */
85  DifferenceVector(3,p[2],p[0],t->p[1]); /* (p_02) t->p_1=p_2-p_0 */
86  DifferenceVector(3,p[1],p[0],t->p[2]); /* (p_01) t->p_2=p_1-p_0 */
87  DifferenceVector(3,p[0],p[1],t->p[3]); /* (d) t->p_3=p_0-p_1-p_2+p_3 */
88  DifferenceVector(3,t->p[3],p[2],t->p[3]);
89  AccumulateVector(3,p[3],t->p[3]); /* t->p[3]+=p[3] */
90  }
91  else
92  {
93  /* For derived patches, we already have the four points computed */
94  for(i=0;i<4;i++)
95  memcpy(t->p[i],p[i],3*sizeof(double));
96  }
97 
98  CrossProduct(t->p[1],t->p[2],t->p[4]); /* (n0) t_p_4=p_0_2 x p_0_1 */
99  CrossProduct(t->p[1],t->p[3],t->p[5]); /* (n1) t_p_5=p_0_2 x d */
100  CrossProduct(t->p[3],t->p[2],t->p[6]); /* (n2) t_p_6=d x p_0_1 */
101 }
102 
103 void CopyTrans(TTrans *t_dst,TTrans *t_src)
104 {
105  unsigned int i;
106 
107  t_dst->t=t_src->t;
108  t_dst->s=t_src->s;
109  t_dst->v=t_src->v;
110  t_dst->u=t_src->u;
111  t_dst->val=t_src->val;
112  if (t_src->ct!=NULL)
113  {
114  NEW(t_dst->ct,1,THTransform);
115  HTransformCopy(t_dst->ct,t_src->ct);
116  }
117  else
118  t_dst->ct=NULL;
119 
120  if (t_src->vect!=NULL)
121  {
122  NEW(t_dst->vect,3,double);
123  memcpy(t_dst->vect,t_src->vect,3*sizeof(double));
124  }
125  else
126  t_dst->vect=NULL;
127 
128  if (t_src->p!=NULL)
129  {
130  NEW(t_dst->p,7,double*);
131  for(i=0;i<7;i++)
132  {
133  NEW(t_dst->p[i],3,double);
134  memcpy(t_dst->p[i],t_src->p[i],3*sizeof(double));
135  }
136  }
137  else
138  t_dst->p=NULL;
139 }
140 
142 {
143  CopyTrans(ti,t);
144  if (ti->t==CT_TRANS)
145  HTransformInverse(ti->ct,ti->ct);
146  else
147  ti->s=-ti->s;
148 }
149 
150 boolean TransHasVar(unsigned int v,TTrans *t)
151 {
152  return((v==t->v)||(v==t->u));
153 }
154 
155 void EvaluateVectorsPATrans(double u,double v,double *x,double *y,double *h,
156  TTrans *t)
157 {
158  if (!IS_PATCH_TRANS(t->t))
159  Error("Using EvaluatePATrans to evaluate a non-PA transform");
160 
161  /* x=n0+u*n1+v*n2 */
162  SumVectorScale(3,t->p[4],u,t->p[5],x);
163  SumVectorScale(3,x,v,t->p[6],x);
164 
165  /* y=p_02+v*d */
166  SumVectorScale(3,t->p[1],v,t->p[3],y);
167 
168  /* t=p_0+u*p_02+v*p_01+u*v*d */
169  SumVectorScale(3,t->p[0],u,t->p[1],h);
170  SumVectorScale(3,h,v,t->p[2],h);
171  SumVectorScale(3,h,u*v,t->p[3],h);
172 }
173 
174 void EvaluateTrans(double v1,double v2,THTransform *a,TTrans *t)
175 {
176  switch (t->t)
177  {
178  case CT_TRANS:
179  HTransformCopy(a,t->ct);
180  break;
181  case TX:
182  HTransformTx(t->s*v1,a);
183  break;
184  case TY:
185  HTransformTy(t->s*v1,a);
186  break;
187  case TZ:
188  HTransformTz(t->s*v1,a);
189  break;
190  case TV:
191  HTransformTxyz(t->s*t->vect[0]*v1,t->s*t->vect[1]*v1,t->s*t->vect[2]*v1,a);
192  break;
193  case RX:
194  HTransformRx(t->s*v1,a);
195  break;
196  case RY:
197  HTransformRy(t->s*v1,a);
198  break;
199  case RZ:
200  HTransformRz(t->s*v1,a);
201  break;
202  case PA:
203  EvaluatePATrans(v1,v2,a,t);
204  break;
205  case dRX:
206  /* With negative sign we have to evaluate the derivative of the
207  inverse. However, for rotations this derivative can be
208  computed directly. */
209  HTransformRx2(t->s*cos(v1),-sin(v1),a);
212  break;
213  case dRY:
214  HTransformRy2(t->s*cos(v1),-sin(v1),a);
217  break;
218  case dRZ:
219  HTransformRz2(t->s*cos(v1),-sin(v1),a);
222  break;
223  case dPA_U:
224  {
225  double nv[3],dnv[3],nx,ny;
226  double x[3],y[3],tr[3];
227  double dx[3],dy[3]={0,0,0},dz[3];
228 
229  /* Get the non-normalized x,y,t vectors (t is only used if t->s<0) */
230  EvaluateVectorsPATrans(v1,v2,x,y,tr,t);
231 
232  /* dx = diff(x_normalized,u) */
233  /* x_norm x = norm(x)
234  For a generic vector'v' depending on a parameter 'u',
235  and with n_v=norm(v) (i.e., n_v is also function of 'u')
236  diff(v/n_v,u)=(1/n_v^2)*[diff(v,u)*n_v-v*diff(n_v,u)]
237  where
238  diff(n_v,u)=1/n_v*diff(v\tr*v,u)
239  =1/n_v*v\tr*diff(v,u)
240  and, thus
241  diff(v/n_v,u) = (1/n_v^2)*[diff(v,u)*n_v
242  -v*1/n_v*v\tr*diff(v,u)]
243  = diff(v,u)/n_v
244  -(v/n_v)*(v\tr/n_v)*(diff(v,u)/n_v)
245 
246  Thus, if v_norm=v/nv and dv_norm=diff(v,u)/norm(v)
247  then diff(v/n_v,u)=dv_norm-(v_norm\tr*dv_norm)*v_norm
248 
249  This is used every time we have to evaluate the
250  differential of a normalized vector w.r.t. a given variable
251  where we have the formula giving the unormalized vector.
252  */
253  nx=Norm(3,x);
254  ScaleVector2(1/nx,3,x,nv);
255  /* t->p[5] = n1 = diff(x,u) */
256  ScaleVector2(1/nx,3,t->p[5],dnv);
257  SumVectorScale(3,dnv,-DotProduct(nv,dnv),nv,dx);
258 
259  /* dy = diff(y_norm,u) is zero */
260 
261  /* dz = diff(z_norm,u) with z_norm = x_norm X y_norm */
262  ny=Norm(3,y);
263  CrossProduct(dx,y,dz);
264  ScaleVector2(1/ny,3,dz,dz);
265 
266  /* dt = diff(p,u) = p_02+v*d = y */
267 
268  /* Set up the matrix */
269  if (t->s>0)
270  {
271  HTransformFromVectors(dx,dy,dz,y,a);
273  }
274  else
275  {
276  /* trans=T*R -> trans\inv=R\tr*(-T)=[R\tr -R\tr*t]
277  diff(trans\inv)=[diff(R\tr) -[diff(R\tr)*t+R\tr*diff(t)]]
278  */
279  THTransform Rt,dR;
280  double h[3],z[3],y1[3];
281  double zero[3]={0,0,0};
282 
283  /* R\tr */
284  ScaleVector2(1/nx,3,x,x);
285  ScaleVector2(1/ny,3,y,y1);
286  CrossProduct(x,y1,z);
287  HTransformFromVectors(x,y1,z,zero,&Rt);
288  HTransformTranspose(&Rt,&Rt);
289 
290  /* a=diff(R\tr) = diff(R)\tr*/
291  HTransformFromVectors(dx,dy,dz,zero,&dR);
293  HTransformTranspose(&dR,a);
294 
295  /* Now set the homogeneous part of 'a' */
296  HTransformApplyRot(tr,h,a); /* h=diff(R\tr)*t */
297  HTransformApplyRot(y,z,&Rt); /* z=R\tr*diff(t) */
298  AccumulateVector(3,z,h); /* h=h+z */
299 
303  }
304  }
305  break;
306  case dPA_V:
307  {
308  double nv[3],dnv[3],nx,ny;
309  double x[3],y[3],tr[3];
310  double dx[3],dy[3],dz[3],dt[3];
311 
312  /* Get the non-normalized x,y,t vectors (t is only used if t->s<0) */
313  EvaluateVectorsPATrans(v1,v2,x,y,tr,t);
314 
315  /* dx = diff(x_normalized,v) */
316  nx=Norm(3,x);
317  ScaleVector2(1/nx,3,x,nv);
318  /* t->p[6] = n2 = diff(x,v) */
319  ScaleVector2(1/nx,3,t->p[6],dnv);
320  SumVectorScale(3,dnv,-DotProduct(nv,dnv),nv,dx);
321 
322  /* dy = diff(y_normalized,v) */
323  ny=Norm(3,y);
324  ScaleVector2(1/ny,3,y,nv);
325  /* t->p[3] = d = diff(y,v) */
326  ScaleVector2(1/ny,3,t->p[3],dnv);
327  SumVectorScale(3,dnv,-DotProduct(nv,dnv),nv,dy);
328 
329  /* dz = diff(z_norm,u) with z_norm = x_norm X y_norm */
330  /* diff(z_norm,v) = diff(x_norm,v) X y/norm(y)
331  + x/norm(x) X diff(y_norm,v) */
332  CrossProduct(dx,y,dz);
333  ScaleVector2(1/ny,3,dz,dz);
334  CrossProduct(x,dy,nv);
335  SumVectorScale(3,dz,1/nx,nv,dz);
336 
337  /* dt = diff(t,v) = p_01+u*d */
338  SumVectorScale(3,t->p[2],v1,t->p[3],dt);
339 
340  if (t->s>0)
341  {
342  /* Set up the matrix */
343  HTransformFromVectors(dx,dy,dz,dt,a);
345  }
346  else
347  {
348  /* trans=T*R -> trans\inv=R\tr*(-T)=[R\tr -R\tr*t]
349  diff(trans\inv)=[diff(R\tr) -[diff(R\tr)*t+R\tr*diff(t)]]
350  */
351  THTransform Rt,dR;
352  double h[3],z[3];
353  double zero[3]={0,0,0};
354 
355  /* R\tr */
356  ScaleVector2(1/nx,3,x,x);
357  ScaleVector2(1/ny,3,y,y);
358  CrossProduct(x,y,z);
359  HTransformFromVectors(x,y,z,zero,&Rt);
360  HTransformTranspose(&Rt,&Rt);
361 
362  /* a=diff(R\tr) = diff(R)\tr*/
363  HTransformFromVectors(dx,dy,dz,zero,&dR);
365  HTransformTranspose(&dR,a);
366 
367  /* Now set the homogeneous part of 'a' */
368  HTransformApplyRot(tr,h,a); /* h=diff(R\tr)*t */
369  HTransformApplyRot(dt,z,&Rt); /* z=R\tr*diff(t) */
370  AccumulateVector(3,z,h); /* h=h+z */
371 
375  }
376  }
377  break;
378  case ddRX:
379  /* With negative sign we have to evaluate the second derivative of the
380  inverse. However, for rotations this derivative can be
381  computed directly. */
382  HTransformRx2(-t->s*sin(v1),-cos(v1),a);
385  break;
386  case ddRY:
387  HTransformRy2(-t->s*sin(v1),-cos(v1),a);
390  break;
391  case ddRZ:
392  HTransformRz2(-t->s*sin(v1),-cos(v1),a);
395  break;
396  case ddPA_UU:
397  case ddPA_UV:
398  case ddPA_VV:
399  Error("The evaluation of the second derivative of parametrized-patch transforms is not implemented yet");
400  break;
401  default:
402  Error("Unknown transform type in EvaluateTrans");
403  }
404 }
405 
406 void EvaluatePATrans(double u,double v,THTransform *a,TTrans *t)
407 {
408  double x[3],y[3],z[3],h[3];
409 
410  EvaluateVectorsPATrans(u,v,x,y,h,t);
411  Normalize(3,x);
412  Normalize(3,y);
413  /* z=x X y */
414  CrossProduct(x,y,z);
415 
416  HTransformFromVectors(x,y,z,h,a);
417  if (t->s<0)
418  HTransformInverse(a,a);
419 }
420 
422 {
423  if (t->ct!=NULL)
424  {
425  HTransformDelete(t->ct);
426  free(t->ct);
427  t->ct=NULL;
428  }
429  if (t->vect!=NULL)
430  {
431  free(t->vect);
432  t->vect=NULL;
433  }
434  if (t->p!=NULL)
435  {
436  unsigned int i;
437 
438  for(i=0;i<7;i++)
439  free(t->p[i]);
440  free(t->p);
441  t->p=NULL;
442  }
443 }
444 
445 
446 /*************************************************************************/
447 /*************************************************************************/
448 /*************************************************************************/
449 
451 {
452  ts->m=INIT_NUM_TERMS_TS;
453  ts->n=0;
454  NEW(ts->t,ts->m,TTrans*);
455 }
456 
457 void CopyTransSeq(TTransSeq *ts_dst,TTransSeq *ts_src)
458 {
459  unsigned int i;
460 
461  ts_dst->m=ts_src->m;
462  ts_dst->n=ts_src->n;
463 
464  NEW(ts_dst->t,ts_dst->m,TTrans *);
465  for(i=0;i<ts_dst->n;i++)
466  {
467  NEW(ts_dst->t[i],1,TTrans);
468  CopyTrans(ts_dst->t[i],ts_src->t[i]);
469  }
470 }
471 
473 {
474  unsigned int i;
475 
476  for(i=0;i<ts->n;i++)
477  {
478  DeleteTrans(ts->t[i]);
479  free(ts->t[i]);
480  }
481  ts->n=0;
482 }
483 
485 {
486  return(ts->n==0);
487 }
488 
490 {
491  unsigned int i;
492  boolean found;
493 
494  found=FALSE;
495  for(i=0;((!found)&&(i<ts->n));i++)
496  found=((ts->t[i]->t==CT_TRANS)&&(!HTransformIsTranslation(ts->t[i]->ct)));
497 
498  return(found);
499 }
500 
501 unsigned int TransSeqSize(TTransSeq *ts)
502 {
503  return(ts->n);
504 }
505 
507 {
508  if (i>=ts->n)
509  Error("Index out of range in GetVarElementFromTransSeq");
510 
511  return(ts->t[i]);
512 }
513 
515 {
516  /* For CT_TRANS we try to compact, if possible */
517  if (t->t==CT_TRANS)
518  {
519  if (t->s>0)
520  AddCtTrans2TransSeq(t->ct,ts);
521  else
522  {
523  THTransform ict;
524 
525  HTransformInverse(t->ct,&ict);
526  AddCtTrans2TransSeq(&ict,ts);
527  HTransformDelete(&ict);
528  }
529  }
530  else
531  {
532  /* For variable transforms compact only if the previous trasform is
533  the identity (this happens for just initialized transform sequences) */
534  if ((ts->n>0)&&(ts->t[ts->n-1]->t==CT_TRANS)&&(HTransformIsIdentity(ts->t[ts->n-1]->ct)))
535  {
536  DeleteTrans(ts->t[ts->n-1]);
537  CopyTrans(ts->t[ts->n-1],t);
538  }
539  else
540  {
541  if (ts->n==ts->m)
542  { MEM_DUP(ts->t,ts->m,TTrans *); }
543  NEW(ts->t[ts->n],1,TTrans);
544  CopyTrans(ts->t[ts->n],t);
545  ts->n++;
546  }
547  }
548 }
549 
551 {
552  if (!HTransformIsIdentity(t))
553  {
554  if ((ts->n>0)&&(ts->t[ts->n-1]->t==CT_TRANS))
555  {
556  HTransformProduct(ts->t[ts->n-1]->ct,t,ts->t[ts->n-1]->ct);
557  /* Identity matrix is removed (except the base one) */
558  if ((HTransformIsIdentity(ts->t[ts->n-1]->ct))&&(ts->n>1))
559  {
560  ts->n--;
561  DeleteTrans(ts->t[ts->n]);
562  free(ts->t[ts->n]);
563  }
564  }
565  else
566  {
567  if (ts->n==ts->m)
568  {
569  MEM_DUP(ts->t,ts->m,TTrans *);
570  }
571  NEW(ts->t[ts->n],1,TTrans);
572  InitCtTrans(t,ts->t[ts->n]);
573  ts->n++;
574  }
575  }
576 }
577 
578 void AddVarTrans2TransSeq(unsigned int t,int s,unsigned int v,TTransSeq *ts)
579 {
580  if (t==CT_TRANS)
581  Error("Adding a constant varaible transform in AddVarTrans2TransSeq");
582 
583  if (IS_PATCH_TRANS(t))
584  Error("Do not use AddVarTrans2TransSeq to add a patch transform to a Trans Seq");
585 
586  if (t==TV)
587  Error("Do not use AddVarTrans2TransSeq to add a displacement transform to a Trans Seq");
588 
589  if ((ts->n>0)&&(ts->t[ts->n-1]->t==CT_TRANS)&&(HTransformIsIdentity(ts->t[ts->n-1]->ct)))
590  InitVarTrans(t,s,v,ts->t[ts->n-1]);
591  else
592  {
593  if (ts->n==ts->m)
594  { MEM_DUP(ts->t,ts->m,TTrans *); }
595  NEW(ts->t[ts->n],1,TTrans);
596  InitVarTrans(t,s,v,ts->t[ts->n]);
597  ts->n++;
598  }
599 }
600 
601 void AddDispTrans2TransSeq(int s,unsigned int v,double *vect,TTransSeq *ts)
602 {
603  if ((ts->n>0)&&(ts->t[ts->n-1]->t==CT_TRANS)&&(HTransformIsIdentity(ts->t[ts->n-1]->ct)))
604  InitTVTrans(s,v,vect,ts->t[ts->n-1]);
605  else
606  {
607  if (ts->n==ts->m)
608  { MEM_DUP(ts->t,ts->m,TTrans *); }
609  NEW(ts->t[ts->n],1,TTrans);
610  InitTVTrans(s,v,vect,ts->t[ts->n]);
611  ts->n++;
612  }
613 }
614 
615 void AddPatchTrans2TransSeq(unsigned int t,int s,unsigned int u,unsigned int v,
616  double **p,TTransSeq *ts)
617 {
618  if ((ts->n>0)&&(ts->t[ts->n-1]->t==CT_TRANS)&&(HTransformIsIdentity(ts->t[ts->n-1]->ct)))
619  InitPatchTrans(t,s,u,v,p,ts->t[ts->n-1]);
620  else
621  {
622  if (ts->n==ts->m)
623  { MEM_DUP(ts->t,ts->m,TTrans *); }
624  NEW(ts->t[ts->n],1,TTrans);
625  InitPatchTrans(t,s,u,v,p,ts->t[ts->n]);
626  ts->n++;
627  }
628 }
629 
630 boolean VarIncludedinTransSeq(unsigned int v,TTransSeq *ts)
631 {
632  boolean found;
633  unsigned int i;
634 
635  found=FALSE;
636  i=0;
637  while ((!found)&&(i<ts->n))
638  {
639  found=TransHasVar(v,ts->t[i]);
640  i++;
641  }
642  return(found);
643 }
644 
645 void UpdateUsedDOF(unsigned int *dof,TTransSeq *ts)
646 {
647  unsigned int i;
648 
649  for(i=0;i<ts->n;i++)
650  {
651  switch (ts->t[i]->t)
652  {
653  case CT_TRANS:
654  break;
655  case TX:
656  dof[TX]++;
657  break;
658  case TY:
659  dof[TY]++;
660  break;
661  case TZ:
662  dof[TZ]++;
663  break;
664  case TV:
665  /* assuming a general displacement. */
666  dof[TX]++;
667  dof[TY]++;
668  dof[TZ]++;
669  break;
670  case PA:
671  case dPA_U:
672  case dPA_V:
673  case ddPA_UU:
674  case ddPA_UV:
675  case ddPA_VV:
676  /* Assuming a general patch */
677  dof[TX]++;
678  dof[TY]++;
679  dof[TZ]++;
680  dof[RX]++;
681  dof[RY]++;
682  dof[RZ]++;
683  break;
684  case RX:
685  case dRX:
686  case ddRX:
687  dof[RX]++;
688  break;
689  case RY:
690  case dRY:
691  case ddRY:
692  dof[RY]++;
693  break;
694  case RZ:
695  case dRZ:
696  case ddRZ:
697  dof[RZ]++;
698  break;
699  default:
700  Error("Unkown transform type in UpdateUsedDOF");
701  }
702  }
703 }
704 
705 void ShiftVariablesInTransSeq(unsigned int nv,TTransSeq *ts)
706 {
707  unsigned int i;
708 
709  for(i=0;i<ts->n;i++)
710  {
711  if (TransHasVar(nv,ts->t[i]))
712  Error("Removing a variable used in a transform sequence");
713  else
714  {
715  if ((ts->t[i]->v!=NO_UINT)&&(ts->t[i]->v>nv))
716  ts->t[i]->v--;
717  if ((ts->t[i]->u!=NO_UINT)&&(ts->t[i]->u>nv))
718  ts->t[i]->u--;
719  }
720  }
721 }
722 
723 boolean FixVarInTransSeq(unsigned int nv,double v,THTransform *ctt,TTransSeq *ts)
724 {
725  unsigned int i,nOrig;
726  TTrans **tOrig;
727  THTransform a;
728  boolean ct;
729 
730  /* Get a copy of the previous array of transfomrs */
731  tOrig=ts->t;
732  nOrig=ts->n;
733 
734  /* And start a new array of transforms */
735  NEW(ts->t,ts->m,TTrans*);
736  ts->n=0;
737  for(i=0;i<nOrig;i++)
738  {
739  if ((tOrig[i]->u!=nv)&&(tOrig[i]->v!=nv))
740  {
741  if ((ts->n==1)&&(ts->t[0]->t==CT_TRANS)&&(HTransformIsIdentity(ts->t[0]->ct)))
742  {
743  DeleteTrans(ts->t[0]);
744  free(ts->t[0]);
745  ts->t[0]=tOrig[i];
746  }
747  else
748  {
749  /* 'nv' not used in this transform: just add it to the new array */
750  ts->t[ts->n]=tOrig[i];
751  ts->n++;
752  }
753  }
754  else
755  {
756  if ((tOrig[i]->t==PA)||(tOrig[i]->t==dPA_U)||(tOrig[i]->t==dPA_V)||
757  (tOrig[i]->t==ddPA_UU)||(tOrig[i]->t==ddPA_UV)||(tOrig[i]->t==ddPA_VV))
758  {
759  /* Transforms that use two variables */
760  if ((tOrig[i]->u==nv)&&(tOrig[i]->v==NO_UINT))
761  {
762  /* Fixing 'u' when 'v' is already fixed */
763  EvaluateTrans(v,tOrig[i]->val,&a,tOrig[i]);
764  AddCtTrans2TransSeq(&a,ts); /* This takes care of compacting
765  ct transforms if necessary */
766  HTransformDelete(&a);
767  DeleteTrans(tOrig[i]);
768  free(tOrig[i]);
769  }
770  else
771  {
772  if ((tOrig[i]->v==nv)&&(tOrig[i]->u==NO_UINT))
773  {
774  /* Fixing 'v' when 'u' is already fixed */
775  EvaluateTrans(tOrig[i]->val,v,&a,tOrig[i]);
776  AddCtTrans2TransSeq(&a,ts); /* This takes care of compacting
777  ct transforms if necessary */
778  HTransformDelete(&a);
779  DeleteTrans(tOrig[i]);
780  free(tOrig[i]);
781  }
782  else
783  {
784  /* only 'u' of 'v' become ct. Just modify the transform and
785  add it to the new array */
786  if (tOrig[i]->u==nv)
787  tOrig[i]->u=NO_UINT; /* Fixing u */
788  else
789  tOrig[i]->v=NO_UINT; /* Fixing v */
790  tOrig[i]->val=v;
791 
792  ts->t[ts->n]=tOrig[i];
793  ts->n++;
794  }
795  }
796  }
797  else
798  {
799  /* Transform that use one variable: become constant */
800  EvaluateTrans(v,0.0,&a,tOrig[i]);
801  AddCtTrans2TransSeq(&a,ts); /* This takes care of compacting
802  ct transforms if necessary */
803  HTransformDelete(&a);
804  DeleteTrans(tOrig[i]);
805  free(tOrig[i]);
806  }
807  }
808  }
809 
810  /* Forget about the previous array of transforms. Individual, non-used
811  elements are already deleted. */
812  free(tOrig);
813 
814  /* Remove the deleted variable. */
816 
817  if ((ts->n>1)||((ts->n==1)&&(ts->t[0]->t!=CT_TRANS)))
818  ct=FALSE; /* non-constant sequence that holds */
819  else
820  {
821  /* zero or one ct transform */
822  ct=TRUE;
823  if (ts->n==0)
824  HTransformIdentity(ctt);
825  else
826  HTransformCopy(ctt,ts->t[0]->ct);
827  }
828  return(ct);
829 }
830 
831 void ReplaceVarInTransSeq(unsigned int nv,unsigned int nvNew,TTransSeq *ts)
832 {
833  unsigned int i;
834 
835  for(i=0;i<ts->n;i++)
836  {
837  if (ts->t[i]->v==nv)
838  ts->t[i]->v=nvNew;
839  if (ts->t[i]->u==nv)
840  ts->t[i]->u=nvNew;
841  }
842 
843  ShiftVariablesInTransSeq(nv,ts);
844 }
845 
847 {
848  if ((ts->n>2)&&(ts->t[0]->t==CT_TRANS)&&(ts->t[ts->n-1]->t==CT_TRANS))
849  {
850  ts->n--;
851  HTransformProduct(ts->t[ts->n]->ct,ts->t[0]->ct,ts->t[0]->ct);
852  DeleteTrans(ts->t[ts->n]);
853  free(ts->t[ts->n]);
854 
855  if (HTransformIsIdentity(ts->t[0]->ct))
856  {
857  unsigned int i;
858 
859  DeleteTrans(ts->t[0]);
860  free(ts->t[0]);
861  for(i=1;i<ts->n;i++)
862  ts->t[i-1]=ts->t[i];
863  ts->n--;
864  }
865  }
866 }
867 
868 void DeriveTransSeq(unsigned int v,unsigned int *n,TTransSeq ***tsd,TTransSeq *ts)
869 {
870  unsigned int i;
871 
872  *n=0;
873  for(i=0;i<ts->n;i++)
874  {
875  if (TransHasVar(v,ts->t[i]))
876  (*n)++;
877  }
878 
879  /* *n will be typically 0 or 1 but it can be larger if a variable is repeated
880  in a loop equation. */
881  if (*n==0)
882  tsd=NULL;
883  else
884  {
885  THTransform a;
886  unsigned int r,t;
887  double sgn;
888 
889  NEW(*tsd,*n,TTransSeq*);
890  for(r=0;r<*n;r++)
891  {
892  /* We derive in turns for each time varible 'v' appears in the
893  sequence. '*n' is the maximum times and 'r' is the time with
894  respect to which we are deriving now. 't' is the numbers
895  of times the variable has been encounterd so far in the
896  scan over the sequence. */
897  t=0;
898  NEW((*tsd)[r],1,TTransSeq);
899  InitTransSeq((*tsd)[r]);
900  for(i=0;i<ts->n;i++)
901  {
902  if ((!TransHasVar(v,ts->t[i]))||(t!=r))
903  AddTrans2TransSeq(ts->t[i],(*tsd)[r]);
904  else
905  {
906  /* The r-th time variable 'v' appears in the sequence */
907  switch (ts->t[i]->t)
908  {
909  case TX:
910  HTransformZero(&a);
911  HTransformSetElement(AXIS_X,AXIS_H,(double)ts->t[i]->s,&a);
912  AddCtTrans2TransSeq(&a,(*tsd)[r]);
913  HTransformDelete(&a);
914  break;
915  case TY:
916  HTransformZero(&a);
917  HTransformSetElement(AXIS_Y,AXIS_H,(double)ts->t[i]->s,&a);
918  AddCtTrans2TransSeq(&a,(*tsd)[r]);
919  HTransformDelete(&a);
920  break;
921  case TZ:
922  HTransformZero(&a);
923  HTransformSetElement(AXIS_Z,AXIS_H,(double)ts->t[i]->s,&a);
924  AddCtTrans2TransSeq(&a,(*tsd)[r]);
925  HTransformDelete(&a);
926  break;
927  case TV:
928  sgn=(double)ts->t[i]->s;
929  HTransformZero(&a);
930  HTransformSetElement(AXIS_X,AXIS_H,sgn*ts->t[i]->vect[0],&a);
931  HTransformSetElement(AXIS_Y,AXIS_H,sgn*ts->t[i]->vect[1],&a);
932  HTransformSetElement(AXIS_Z,AXIS_H,sgn*ts->t[i]->vect[2],&a);
933  AddCtTrans2TransSeq(&a,(*tsd)[r]);
934  HTransformDelete(&a);
935  break;
936  case RX:
937  AddVarTrans2TransSeq(dRX,ts->t[i]->s,ts->t[i]->v,
938  (*tsd)[r]);
939  break;
940  case RY:
941  AddVarTrans2TransSeq(dRY,ts->t[i]->s,ts->t[i]->v,
942  (*tsd)[r]);
943  break;
944  case RZ:
945  AddVarTrans2TransSeq(dRZ,ts->t[i]->s,ts->t[i]->v,
946  (*tsd)[r]);
947  break;
948  case PA:
949  /* For parametrized transforms, we keep all the
950  information changing the type of transform */
951  if (v==ts->t[i]->u) /* Derivative w.r.t. the 1st param */
952  AddPatchTrans2TransSeq(dPA_U,ts->t[i]->s,ts->t[i]->u,
953  ts->t[i]->v,ts->t[i]->p,(*tsd)[r]);
954  else /* Derivative w.r.t. the 2nd param */
955  AddPatchTrans2TransSeq(dPA_V,ts->t[i]->s,ts->t[i]->u,
956  ts->t[i]->v,ts->t[i]->p,(*tsd)[r]);
957  break;
958  case dRX:
959  AddVarTrans2TransSeq(ddRX,ts->t[i]->s,
960  ts->t[i]->v,(*tsd)[r]);
961  break;
962  case dRY:
963  AddVarTrans2TransSeq(ddRY,ts->t[i]->s,
964  ts->t[i]->v,(*tsd)[r]);
965  break;
966  case dRZ:
967  AddVarTrans2TransSeq(ddRZ,ts->t[i]->s,
968  ts->t[i]->v,(*tsd)[r]);
969  break;
970  case dPA_U:
971  if (v==ts->t[i]->u) /* du du */
972  AddPatchTrans2TransSeq(ddPA_UU,ts->t[i]->s,ts->t[i]->u,
973  ts->t[i]->v,ts->t[i]->p,(*tsd)[r]);
974  else /* du dv */
975  AddPatchTrans2TransSeq(ddPA_UV,ts->t[i]->s,ts->t[i]->u,
976  ts->t[i]->v,ts->t[i]->p,(*tsd)[r]);
977  break;
978  case dPA_V:
979  if (v==ts->t[i]->u) /* dv du */
980  AddPatchTrans2TransSeq(ddPA_UV,ts->t[i]->s,ts->t[i]->u,
981  ts->t[i]->v,ts->t[i]->p,(*tsd)[r]);
982  else /* dv dv */
983  AddPatchTrans2TransSeq(ddPA_VV,ts->t[i]->s,ts->t[i]->u,
984  ts->t[i]->v,ts->t[i]->p,(*tsd)[r]);
985  break;
986  default:
987  Error("Unknown transform type in DeriveTransSeq");
988  }
989  }
990  if (TransHasVar(v,ts->t[i]))
991  t++;
992  }
993  }
994  }
995 }
996 
997 void EvaluateTransSeq(double *v,THTransform *r,TTransSeq *ts)
998 {
999  unsigned int i;
1000  THTransform a;
1001  double val;
1002  double d1,d2,d3;
1003 
1004  HTransformIdentity(r);
1005  for(i=0;i<ts->n;i++)
1006  {
1007  /* For the more usual transform we accumulate instad than
1008  generating a transform and using product. */
1009  switch (ts->t[i]->t)
1010  {
1011  case CT_TRANS:
1012  HTransformProduct(r,ts->t[i]->ct,r);
1013  break;
1014  case TX:
1015  d1=((double)(ts->t[i]->s))*v[ts->t[i]->v];
1016  HTransformAcumTrans(d1,0,0,r);
1017  break;
1018  case TY:
1019  d1=((double)(ts->t[i]->s))*v[ts->t[i]->v];
1020  HTransformAcumTrans(0,d1,0,r);
1021  break;
1022  case TZ:
1023  d1=((double)(ts->t[i]->s))*v[ts->t[i]->v];
1024  HTransformAcumTrans(0,0,d1,r);
1025  break;
1026  case TV:
1027  val=((double)(ts->t[i]->s))*v[ts->t[i]->v];
1028  d1=ts->t[i]->vect[0];
1029  d2=ts->t[i]->vect[1];
1030  d3=ts->t[i]->vect[2];
1031  HTransformAcumTrans(val*d1,val*d2,val*d3,r);
1032  break;
1033  case RX:
1034  val=((double)(ts->t[i]->s))*v[ts->t[i]->v];
1035  HTransformAcumRot(RX,sin(val),cos(val),r);
1036  break;
1037  case RY:
1038  val=((double)(ts->t[i]->s))*v[ts->t[i]->v];
1039  HTransformAcumRot(RY,sin(val),cos(val),r);
1040  break;
1041  case RZ:
1042  val=((double)(ts->t[i]->s))*v[ts->t[i]->v];
1043  HTransformAcumRot(RZ,sin(val),cos(val),r);
1044  break;
1045  case PA:
1046  case dPA_U:
1047  case dPA_V:
1048  case ddPA_UU:
1049  case ddPA_UV:
1050  case ddPA_VV:
1051  d1=(ts->t[i]->u==NO_UINT?ts->t[i]->val:v[ts->t[i]->u]);
1052  d2=(ts->t[i]->v==NO_UINT?ts->t[i]->val:v[ts->t[i]->v]);
1053  EvaluateTrans(d1,d2,&a,ts->t[i]);
1054  HTransformProduct(r,&a,r);
1055  HTransformDelete(&a);
1056  break;
1057  case dRX:
1058  case dRY:
1059  case dRZ:
1060  case ddRX:
1061  case ddRY:
1062  case ddRZ:
1063  val=v[ts->t[i]->v];
1064  EvaluateTrans(val,0.0,&a,ts->t[i]);
1065  HTransformProduct(r,&a,r);
1066  HTransformDelete(&a);
1067  break;
1068  default:
1069  Error("Unknown transform type in EvaluateTransSeq");
1070  }
1071  }
1072 }
1073 
1074 void PrintTransSeq(FILE *f,char **varNames,TTransSeq *ts)
1075 {
1076  unsigned int i,j,k,t;
1077  double val;
1078 
1079  for(i=0;i<ts->n;i++)
1080  {
1081  t=ts->t[i]->t;
1082 
1083  switch (t)
1084  {
1085  case CT_TRANS:
1086  if (HTransformIsIdentity(ts->t[i]->ct))
1087  fprintf(f,"Id");
1088  else
1089  {
1090  //HTransformPrettyPrint(f,ts->t[i]->ct);
1091 
1092  fprintf(f,"T(");
1093  for(j=0;j<DIM_SP;j++)
1094  {
1095  for(k=0;k<(DIM_SP+1);k++)
1096  {
1097  val=HTransformGetElement(j,k,ts->t[i]->ct);
1098  PrintReal(f,val);
1099  if (k<DIM_SP)
1100  fprintf(f,",");
1101  }
1102  if (j<DIM_SP-1)
1103  fprintf(f,";");
1104  }
1105  fprintf(f,")");
1106  }
1107  break;
1108 
1109  case TX:
1110  fprintf(f,"Tx(");
1111  break;
1112  case TY:
1113  fprintf(f,"Ty(");
1114  break;
1115  case TZ:
1116  fprintf(f,"Tz(");
1117  break;
1118  case TV:
1119  fprintf(f,"Tv(");
1120  PrintReal(f,ts->t[i]->vect[0]);fprintf(f,",");
1121  PrintReal(f,ts->t[i]->vect[1]);fprintf(f,",");
1122  PrintReal(f,ts->t[i]->vect[2]);fprintf(f,",");
1123  break;
1124  case RX:
1125  fprintf(f,"Rx(");
1126  break;
1127  case RY:
1128  fprintf(f,"Ry(");
1129  break;
1130  case RZ:
1131  fprintf(f,"Rz(");
1132  break;
1133  case PA:
1134  case dPA_U:
1135  case dPA_V:
1136  case ddPA_UU:
1137  case ddPA_UV:
1138  case ddPA_VV:
1139  {
1140  unsigned int k;
1141  double v[3];
1142 
1143  switch (t)
1144  {
1145  case PA:
1146  fprintf(f,"Pa(");
1147  break;
1148  case dPA_U:
1149  fprintf(f,"dPa_u(");
1150  break;
1151  case dPA_V:
1152  fprintf(f,"dPa_v(");
1153  break;
1154  case ddPA_UU:
1155  fprintf(f,"ddPa_uu(");
1156  break;
1157  case ddPA_UV:
1158  fprintf(f,"ddPa_uv(");
1159  break;
1160  case ddPA_VV:
1161  fprintf(f,"ddPa_vv(");
1162  break;
1163  }
1164  /* Print the 4 vectors defining the patch */
1165  if (t!=PA)
1166  {
1167  /* For derived patches we print the already
1168  processed patch extremes +
1169  Derived patches typically do not appear in
1170  equation files */
1171  for(j=0;j<4;j++)
1172  {
1173  for(k=0;k<3;k++)
1174  {
1175  PrintReal(f,ts->t[i]->p[j][k]);
1176  if (k<2) fprintf(f,",");
1177  }
1178  fprintf(f,";");
1179  }
1180  }
1181  else
1182  {
1183  /* For oritinal patches we print the
1184  orignal extremes. This facilitates the
1185  unsderstanding of equation files. */
1186  /* p_0 */
1187  for(k=0;k<3;k++)
1188  {
1189  PrintReal(f,ts->t[i]->p[0][k]);
1190  if (k<2) fprintf(f,",");
1191  }
1192  fprintf(f,";");
1193  /* p_1=p_01+p_0 */
1194  SumVector(3,ts->t[i]->p[2],ts->t[i]->p[0],v);
1195  for(k=0;k<3;k++)
1196  {
1197  PrintReal(f,v[k]);
1198  if (k<2) fprintf(f,",");
1199  }
1200  fprintf(f,";");
1201  /* p_2=p_02+p_0 */
1202  SumVector(3,ts->t[i]->p[1],ts->t[i]->p[0],v);
1203  for(k=0;k<3;k++)
1204  {
1205  PrintReal(f,v[k]);
1206  if (k<2) fprintf(f,",");
1207  }
1208  }
1209  fprintf(f,";");
1210  /* p_3=d+p_01+p_02+p_0 */
1211  SumVector(3,ts->t[i]->p[3],ts->t[i]->p[2],v);
1212  AccumulateVector(3,ts->t[i]->p[1],v);
1213  AccumulateVector(3,ts->t[i]->p[0],v);
1214  for(k=0;k<3;k++)
1215  {
1216  PrintReal(f,v[k]);
1217  if (k<2) fprintf(f,",");
1218  }
1219  fprintf(f,";");
1220 
1221  /* Now the variables */
1222  if (ts->t[i]->u==NO_UINT)
1223  PrintReal(f,ts->t[i]->val);
1224  else
1225  {
1226  if (varNames!=NULL)
1227  {
1228  char *n;
1229 
1230  n=varNames[ts->t[i]->u];
1231  PRINT_VARIABLE_NAME(f,n);
1232  }
1233  else
1234  fprintf(f,"v_%u",ts->t[i]->u);
1235  }
1236  fprintf(f,",");
1237  }
1238  break;
1239  case dRX:
1240  fprintf(f,"dRx(");
1241  break;
1242  case dRY:
1243  fprintf(f,"dRy(");
1244  break;
1245  case dRZ:
1246  fprintf(f,"dRz(");
1247  break;
1248  case ddRX:
1249  fprintf(f,"ddRx(");
1250  break;
1251  case ddRY:
1252  fprintf(f,"ddRy(");
1253  break;
1254  case ddRZ:
1255  fprintf(f,"ddRz(");
1256  break;
1257  default:
1258  Error("Unknown transform type in EvaluateTransSeq");
1259  }
1260 
1261  if (ts->t[i]->t!=CT_TRANS)
1262  {
1263  if (ts->t[i]->v==NO_UINT)
1264  PrintReal(f,ts->t[i]->val);
1265  else
1266  {
1267  if (varNames!=NULL)
1268  {
1269  char *n;
1270 
1271  n=varNames[ts->t[i]->v];
1272  PRINT_VARIABLE_NAME(f,n);
1273  }
1274  else
1275  fprintf(f,"v_%u",ts->t[i]->v);
1276  }
1277  fprintf(f,")");
1278  }
1279 
1280  if (ts->t[i]->s<0)
1281  fprintf(f,"^-1");
1282 
1283  if (i<(ts->n-1))
1284  fprintf(f,"*");
1285  }
1286 }
1287 
1289 {
1290  ResetTransSeq(ts);
1291  free(ts->t);
1292 }
void UpdateUsedDOF(unsigned int *dof, TTransSeq *ts)
Determines the dof used in a transform sequence.
Definition: trans_seq.c:645
#define AXIS_X
One of the dimension of R^3.
Definition: htransform.h:83
Definition of basic functions.
double val
Definition: trans_seq.h:141
void HTransformRz2(double s, double c, THTransform *t)
Constructor.
Definition: htransform.c:232
#define FALSE
FALSE.
Definition: boolean.h:30
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
boolean VarIncludedinTransSeq(unsigned int v, TTransSeq *ts)
Determines if the sequence includes a given variable.
Definition: trans_seq.c:630
#define dPA_V
Derivative of a PA transform.
Definition: trans_seq.h:70
boolean TransHasVar(unsigned int v, TTrans *t)
Identifies if a variable is involved in a given transform.
Definition: trans_seq.c:150
#define ddPA_VV
Double derivative of a PA transform.
Definition: trans_seq.h:109
#define NEW(_var, _n, _type)
Allocates memory space.
Definition: defines.h:385
#define ddRX
Double derivative of a Rx transform.
Definition: trans_seq.h:76
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.
void ReplaceVarInTransSeq(unsigned int nv, unsigned int nvNew, TTransSeq *ts)
Replaces a variable.
Definition: trans_seq.c:831
unsigned int v
Definition: trans_seq.h:139
#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 double Norm(unsigned int s, double *v)
Computes the norm of a vector.
CBLAS_INLINE void SumVector(unsigned int s, double *v1, double *v2, double *v)
Adds two vectors.
Definition: basic_algebra.c:67
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
void TransInvert(TTrans *ti, TTrans *t)
Invert a transform.
Definition: trans_seq.c:141
void CopyTransSeq(TTransSeq *ts_dst, TTransSeq *ts_src)
Constructor.
Definition: trans_seq.c:457
#define INIT_NUM_TERMS_TS
Initial room for terms in a transform sequence.
Definition: trans_seq.h:117
CBLAS_INLINE void AccumulateVector(unsigned int s, double *v1, double *v2)
Adds a vector to another vectors.
Definition: basic_algebra.c:55
void AddVarTrans2TransSeq(unsigned int t, int s, unsigned int v, TTransSeq *ts)
Adds a variable transform to the sequence.
Definition: trans_seq.c:578
void EvaluatePATrans(double u, double v, THTransform *a, TTrans *t)
Evaluates a PA transform.
Definition: trans_seq.c:406
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 dRX
Derivative of a Rx transform.
Definition: trans_seq.h:44
#define RY
One of the types of homogeneous transforms in R^3.
Definition: htransform.h:67
#define TRUE
TRUE.
Definition: boolean.h:21
CBLAS_INLINE void Normalize(unsigned int s, double *v)
Normalizes a vector.
void ResetTransSeq(TTransSeq *ts)
Semi-destructor.
Definition: trans_seq.c:472
void Error(const char *s)
General error function.
Definition: error.c:80
#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
void InitPatchTrans(unsigned int tp, int s, unsigned int u, unsigned int v, double **p, TTrans *t)
Initializes a parametrized-patch transform.
Definition: trans_seq.c:61
#define ddPA_UU
Double derivative of a PA transform.
Definition: trans_seq.h:95
Sequence (product) of homogeneous transforms.
void DeleteTrans(TTrans *t)
Destructor.
Definition: trans_seq.c:421
boolean HTransformIsTranslation(THTransform *t)
Identify the translation matrices.
Definition: htransform.c:102
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 ddRZ
Double derivative of a Rx transform.
Definition: trans_seq.h:88
void AddCtTrans2TransSeq(THTransform *t, TTransSeq *ts)
Adds a constant transform to the sequence.
Definition: trans_seq.c:550
double DotProduct(double *v1, double *v2)
Computes the dot product of two 3d vectors.
Definition: geom.c:652
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
CBLAS_INLINE void ScaleVector2(double f, unsigned int s, double *v, double *vout)
Scales a vector.
Definition: basic_algebra.c:42
unsigned int TransSeqSize(TTransSeq *ts)
Number of elements in the transform sequence.
Definition: trans_seq.c:501
#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 PRINT_VARIABLE_NAME(f, name)
Prints a variable name into a file.
Definition: defines.h:427
A step in a transform sequence.
Definition: trans_seq.h:136
THTransform * ct
Definition: trans_seq.h:150
void CopyTrans(TTrans *t_dst, TTrans *t_src)
Constructor.
Definition: trans_seq.c:103
void DifferenceVector(unsigned int s, double *v1, double *v2, double *v)
Substracts two vectors.
double * vect
Definition: trans_seq.h:152
void AddTrans2TransSeq(TTrans *t, TTransSeq *ts)
Adds a transform to a transform sequence.
Definition: trans_seq.c:514
unsigned int n
Definition: trans_seq.h:321
void DeriveTransSeq(unsigned int v, unsigned int *n, TTransSeq ***tsd, TTransSeq *ts)
Derive a sequence of transforms.
Definition: trans_seq.c:868
#define dPA_U
Derivative of a PA transform.
Definition: trans_seq.h:63
A sequence of transforms.
Definition: trans_seq.h:319
TTrans ** t
Definition: trans_seq.h:322
void PrintReal(FILE *f, double r)
Pretty print a real number.
Definition: geom.c:745
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 ddRY
Double derivative of a Rx transform.
Definition: trans_seq.h:82
void EvaluateTransSeq(double *v, THTransform *r, TTransSeq *ts)
Evaluates the transform sequence.
Definition: trans_seq.c:997
#define dRZ
Derivative of a Rz transform.
Definition: trans_seq.h:56
void DeleteTransSeq(TTransSeq *ts)
Destructor.
Definition: trans_seq.c:1288
boolean HasCtRotTransSeq(TTransSeq *ts)
Checks if the tranform sequence includes contant rotations.
Definition: trans_seq.c:489
void InitCtTrans(THTransform *ct, TTrans *t)
Initializes a constant transform.
Definition: trans_seq.c:21
#define MEM_DUP(_var, _n, _type)
Duplicates a previously allocated memory space.
Definition: defines.h:414
unsigned int t
Definition: trans_seq.h:137
#define NO_UINT
Used to denote an identifier that has not been initialized.
Definition: defines.h:435
CBLAS_INLINE void SumVectorScale(unsigned int s, double *v1, double w, double *v2, double *v)
Adds two vectors with a scale.
Definition: basic_algebra.c:86
#define RX
One of the types of homogeneous transforms in R^3.
Definition: htransform.h:59
#define dRY
Derivative of a Ry transform.
Definition: trans_seq.h:50
void AddDispTrans2TransSeq(int s, unsigned int v, double *vect, TTransSeq *ts)
Adds a displacement transform to the sequence.
Definition: trans_seq.c:601
void HTransformTx(double tx, THTransform *t)
Constructor.
Definition: htransform.c:112
void EvaluateTrans(double v1, double v2, THTransform *a, TTrans *t)
Evaluates a transform.
Definition: trans_seq.c:174
#define IS_PATCH_TRANS(t)
Checks if a transform is a parametrized patch (or derived).
Definition: trans_seq.h:126
void EvaluateVectorsPATrans(double u, double v, double *x, double *y, double *h, TTrans *t)
Computes the vectors defining a PA transform.
Definition: trans_seq.c:155
void ShiftVariablesInTransSeq(unsigned int nv, TTransSeq *ts)
Adjust variable indices after removing a variable.
Definition: trans_seq.c:705
void HTransformDelete(THTransform *t)
Destructor.
Definition: htransform.c:887
int s
Definition: trans_seq.h:148
#define PA
Point on a patch.
Definition: trans_seq.h:31
void InitTVTrans(int s, unsigned int v, double *vect, TTrans *t)
Initializes a TV transform.
Definition: trans_seq.c:48
#define ddPA_UV
Double derivative of a PA transform.
Definition: trans_seq.h:102
TTrans * GetElementFromTransSeq(unsigned int i, TTransSeq *ts)
Returns an element from a transform sequence.
Definition: trans_seq.c:506
void HTransformSetElement(unsigned int i, unsigned int j, double v, THTransform *t)
Sets an element in a homogeneous transform.
Definition: htransform.c:312
void PrintTransSeq(FILE *f, char **varNames, TTransSeq *ts)
Prints a transform sequence to a file.
Definition: trans_seq.c:1074
#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
#define TV
Displacement along a vector.
Definition: trans_seq.h:24
boolean IsEmptyTransSeq(TTransSeq *ts)
Identify empty transform sequences.
Definition: trans_seq.c:484
void InitTransSeq(TTransSeq *ts)
Constructor.
Definition: trans_seq.c:450
#define CT_TRANS
Constant transform.
Definition: trans_seq.h:38
void HTransformRy(double ry, THTransform *t)
Constructor.
Definition: htransform.c:178
void HTransformIdentity(THTransform *t)
Constructor.
Definition: htransform.c:69
unsigned int m
Definition: trans_seq.h:320
void CrossProduct(double *v1, double *v2, double *v3)
Computes the cross product of two 3d vectors.
Definition: geom.c:639
void HTransformRy2(double s, double c, THTransform *t)
Constructor.
Definition: htransform.c:222
void AddPatchTrans2TransSeq(unsigned int t, int s, unsigned int u, unsigned int v, double **p, TTransSeq *ts)
Adds a Parametrized-Patch transform to a transform sequence.
Definition: trans_seq.c:615
void InitVarTrans(unsigned int tp, int s, unsigned int v, TTrans *t)
Initializes a variable transform.
Definition: trans_seq.c:34
double ** p
Definition: trans_seq.h:153
void HTransformRx2(double s, double c, THTransform *t)
Constructor.
Definition: htransform.c:212
boolean FixVarInTransSeq(unsigned int nv, double v, THTransform *ctt, TTransSeq *ts)
Set a variable to a constant value.
Definition: trans_seq.c:723
void SimplifyTransSeq(TTransSeq *ts)
Reduces the complexity of the tranform sequence.
Definition: trans_seq.c:846
#define TY
One of the types of homogeneous transforms in R^3.
Definition: htransform.h:43
unsigned int u
Definition: trans_seq.h:138
boolean HTransformIsIdentity(THTransform *t)
Identify the identity matrix.
Definition: htransform.c:91