The Cuik KD-Tree Library


rectangle.c

Go to the documentation of this file.
00001 #include "rectangle.h"
00002 
00003 #include "random.h"
00004 
00005 #include <string.h>
00006 #include <stdlib.h>
00007 #include <math.h>
00008 #include <assert.h>
00009 
00010 
00019 void InitRectangle(unsigned int dim,double *l,double *u,Trectangle *b)
00020 {
00021   assert(dim>0);
00022 
00023   b->n=dim;
00024 
00025   NEW(b->l,2*b->n,double);
00026   if (l!=NULL)
00027     memcpy(b->l,l,b->n*sizeof(double));
00028   else
00029     {
00030       unsigned int i;
00031       for(i=0;i<dim;i++)
00032         b->l[i]=0;
00033     }
00034 
00035   b->u=&(b->l[b->n]);
00036   if (u!=NULL)
00037     memcpy(b->u,u,b->n*sizeof(double));
00038   else
00039     {
00040       unsigned int i;
00041       for(i=0;i<dim;i++)
00042         b->u[i]=0;
00043     }
00044 }
00045 
00046 void InitRectangleFromPoint(unsigned int dim,double *p,Trectangle *b)
00047 {
00048   unsigned int i;
00049 
00050   assert(dim>0);
00051 
00052   b->n=dim;
00053 
00054   NEW(b->l,2*b->n,double);
00055   b->u=&(b->l[b->n]);
00056   for(i=0;i<b->n;i++)
00057     b->l[i]=b->u[i]=p[i];
00058 }
00059 
00060 unsigned int GetRectangleDim(Trectangle *b)
00061 {
00062   return(b->n);
00063 }
00064 
00065 void ExpandRectangle(double *p,Trectangle *b)
00066 {
00067    unsigned int i; 
00068    
00069    for(i=0;i<b->n;i++)
00070      {
00071        if (p[i]<b->l[i])
00072          b->l[i]=p[i];
00073        else
00074          {
00075            if (p[i]>b->u[i])
00076              b->u[i]=p[i];
00077          }
00078      }
00079 }
00080 
00081 double EnlargeRectangleWithLimits(double r,Trectangle *limits,
00082                                   Trectangle *bIn,Trectangle *bOut)
00083 {
00084   unsigned int i; 
00085   double s,v;
00086 
00087   assert(bIn->n==limits->n);
00088 
00089   v=1.0;
00090 
00091   bOut->n=bIn->n;
00092   NEW(bOut->l,2*bOut->n,double);
00093   bOut->u=&(bOut->l[bOut->n]);
00094 
00095   for(i=0;i<bIn->n;i++)
00096     {
00097       s=bIn->l[i]-r;
00098       bOut->l[i]=(s>limits->l[i]?s:limits->l[i]);
00099 
00100       s=bIn->u[i]+r;
00101       bOut->u[i]=(s<limits->u[i]?s:limits->u[i]);
00102 
00103       v*=(bOut->u[i]-bOut->l[i]);
00104     }
00105   return(v);
00106 }
00107 
00108 void CopyRectangle(Trectangle *b_out,Trectangle *b_in)
00109 {
00110   b_out->n=b_in->n;
00111 
00112   NEW(b_out->l,2*b_out->n,double);
00113   memcpy(b_out->l,b_in->l,2*b_out->n*sizeof(double));
00114 
00115   b_out->u=&(b_out->l[b_out->n]);
00116 }
00117 
00118 double GetRectangleLowerLimit(unsigned int i,Trectangle *b)
00119 {
00120   assert(i<b->n);
00121 
00122   return(b->l[i]);
00123 }
00124 
00125 double GetRectangleUpperLimit(unsigned int i,Trectangle *b)
00126 {
00127   assert(i<b->n);
00128 
00129   return(b->u[i]);
00130 }
00131 
00132 void GetRectangleLimits(unsigned int i,double *l,double *u,Trectangle *b)
00133 {
00134   assert(i<b->n);
00135 
00136   *l=b->l[i];
00137   *u=b->u[i];
00138 }
00139 
00140 void SetRectangleLowerLimit(unsigned int i,double l,Trectangle *b)
00141 {
00142   assert(i<b->n);
00143 
00144   b->l[i]=l;
00145 }
00146 
00147 void SetRectangleUpperLimit(unsigned int i,double u,Trectangle *b)
00148 {
00149   assert(i<b->n);
00150 
00151   b->u[i]=u;
00152 }
00153 
00154 void SetRectangleLimits(unsigned int i,double l,double u,Trectangle *b)
00155 {
00156   assert(i<b->n);
00157 
00158   b->l[i]=l;
00159   b->u[i]=u;
00160 }
00161 
00162 void RandomPointInRectangle(double *c,Trectangle *b)
00163 {
00164   unsigned int i;
00165   
00166   for(i=0;i<b->n;i++)
00167     c[i]=b->l[i]+randomDouble()*(b->u[i]-b->l[i]);
00168 }
00169 
00170 double SquaredDistanceToRectangleDimension(unsigned int dim,double p,unsigned int *tp,Trectangle *b)
00171 {
00172   double l,u,d,c,d1,d2;
00173   
00174   assert(dim<b->n);
00175 
00176   l=b->l[dim];
00177   u=b->u[dim];
00178   d=0.0;
00179   if ((tp==NULL)||(tp[dim]==TOPOLOGY_R))
00180     {
00181       if (p<l)
00182         d=l-p;
00183       else
00184         {
00185           if (p>u)
00186             d=p-u;
00187         }
00188     }
00189   else
00190     {
00191       /* We interpret the intervals on the circle as
00192          those from the lower vaule to the higher one,
00193          after putting the values in the [-pi,pi] range. 
00194          In general our intervals are always in this
00195          range and thus, no confusion arise. */
00196       PI2PI(l);
00197       PI2PI(u);
00198 
00199       if (u<l)
00200         SWAP(l,u,c);
00201 
00202       c=p;
00203       PI2PI(c);
00204         
00205       if (c<l)
00206         {
00207           d1=l-c;
00208           if (d1>M_PI) d1=M_2PI-d1;
00209           d2=u-c;
00210           if (d2>M_PI) d2=M_2PI-d2;
00211           d=(d1<d2?d1:d2);
00212         }
00213       else
00214         {
00215           if (c>u)
00216             {
00217               d1=c-l;
00218               if (d1>M_PI) d1=M_2PI-d1;
00219               d2=c-u;
00220               if (d2>M_PI) d2=M_2PI-d2;
00221               d=(d1<d2?d1:d2);
00222             }
00223         }
00224     }
00225   return(d*d);
00226 }
00227 
00228 
00229 double SquaredDistanceToRectangle(double t2,double *p,unsigned int *tp,Trectangle *b)
00230 {
00231   unsigned int i;
00232   double l,u,d,v,c,d1,d2;
00233   
00234   d=0.0;
00235   if (tp==NULL)
00236     {
00237       for(i=0;((i<b->n)&&(d<t2));i++)
00238         {
00239           l=b->l[i];
00240           u=b->u[i];
00241 
00242           if (p[i]<l)
00243             {
00244               v=l-p[i];
00245               d+=v*v;
00246             }
00247           else
00248             {
00249               if (p[i]>u)
00250                 {
00251                   v=p[i]-u;
00252                   d+=v*v;
00253                 }
00254             }
00255         }
00256     }
00257   else
00258     {
00259       for(i=0;((i<b->n)&&(d<t2));i++)
00260         {
00261           l=b->l[i];
00262           u=b->u[i];
00263 
00264           if (tp[i]==TOPOLOGY_R)
00265             {
00266               if (p[i]<l)
00267                 {
00268                   v=l-p[i];
00269                   d+=v*v;
00270                 }
00271               else
00272                 {
00273                   if (p[i]>u)
00274                     {
00275                       v=p[i]-u;
00276                       d+=v*v;
00277                     }
00278                 }
00279             }
00280           else
00281             {
00282               /* We interpret the intervals on the circle as
00283                  those from the lower vaule to the higher one,
00284                  after putting the values in the [-pi,pi] range. 
00285                  In general our intervals are always in this
00286                  range and thus, no confusion arise. */
00287               PI2PI(l);
00288               PI2PI(u);
00289 
00290               if (u<l)
00291                 SWAP(l,u,c);
00292 
00293               c=p[i];
00294               PI2PI(c);
00295 
00296               if (c<l)
00297                 {
00298                   d1=l-c;
00299                   if (d1>M_PI) d1=M_2PI-d1;
00300                   d2=u-c;
00301                   if (d2>M_PI) d2=M_2PI-d2;
00302                   v=(d1<d2?d1:d2);
00303                   d+=v*v;
00304                 }
00305               else
00306                 {
00307                   if (c>u)
00308                     {
00309                       d1=c-l;
00310                       if (d1>M_PI) d1=M_2PI-d1;
00311                       d2=c-u;
00312                       if (d2>M_PI) d2=M_2PI-d2;
00313                       v=(d1<d2?d1:d2);
00314                       d+=v*v;
00315                     }
00316                 }
00317             }
00318         }
00319     }
00320 
00321   return(d);
00322 }
00323 
00324 unsigned int GetRectangleSplitDim(Trectangle *b)
00325 {
00326   unsigned int i;
00327   unsigned int i_max;
00328   double s;
00329   double s_max;
00330       
00331   i_max=0;
00332   s_max=-1.0;
00333   for(i=0;i<b->n;i++)
00334     {
00335       s=(b->u[i]-b->l[i]);
00336       if (s>s_max)
00337         {
00338           s_max=s;
00339           i_max=i;
00340         }
00341     }
00342      
00343   return(i_max);
00344 }
00345 
00346 void DeleteRectangle(Trectangle *b)
00347 {
00348   free(b->l);
00349 }