The Cuik KD-Tree Library


rectangle.c
Go to the documentation of this file.
1 #include "rectangle.h"
2 
3 #include "random.h"
4 #include "definitions.h"
5 
6 #include <string.h>
7 #include <stdlib.h>
8 #include <math.h>
9 #include <assert.h>
10 
11 
20 void InitRectangle(unsigned int dim,double *l,double *u,Trectangle *b)
21 {
22  assert(dim>0);
23 
24  b->n=dim;
25 
26  NEWZ(b->l,2*b->n,double);
27  if (l!=NULL)
28  memcpy(b->l,l,b->n*sizeof(double));
29 
30  b->u=&(b->l[b->n]);
31  if (u!=NULL)
32  memcpy(b->u,u,b->n*sizeof(double));
33 }
34 
35 void InitRectangleFromPoint(unsigned int dim,double *p,Trectangle *b)
36 {
37  assert(dim>0);
38 
39  b->n=dim;
40 
41  NEW(b->l,2*b->n,double);
42  b->u=&(b->l[b->n]);
43  memcpy(b->l,p,b->n*sizeof(double));
44  memcpy(b->u,p,b->n*sizeof(double));
45 }
46 
47 inline unsigned int GetRectangleDim(Trectangle *b)
48 {
49  return(b->n);
50 }
51 
52 void ExpandRectangle(double *p,Trectangle *b)
53 {
54  unsigned int i;
55 
56  for(i=0;i<b->n;i++)
57  {
58  if (p[i]<b->l[i])
59  b->l[i]=p[i];
60  else
61  {
62  if (p[i]>b->u[i])
63  b->u[i]=p[i];
64  }
65  }
66 }
67 
68 double EnlargeRectangleWithLimits(double r,Trectangle *limits,
69  Trectangle *bIn,Trectangle *bOut)
70 {
71  unsigned int i;
72  double s,v;
73 
74  assert(bIn->n==limits->n);
75  assert(bOut->n==bIn->n);
76 
77  v=1.0;
78  for(i=0;i<bIn->n;i++)
79  {
80  s=bIn->l[i]-r;
81  bOut->l[i]=(s>limits->l[i]?s:limits->l[i]);
82 
83  s=bIn->u[i]+r;
84  bOut->u[i]=(s<limits->u[i]?s:limits->u[i]);
85 
86  v*=(bOut->u[i]-bOut->l[i]);
87  }
88  return(v);
89 }
90 
92 {
93  b_out->n=b_in->n;
94 
95  NEW(b_out->l,2*b_out->n,double);
96  memcpy(b_out->l,b_in->l,2*b_out->n*sizeof(double));
97 
98  b_out->u=&(b_out->l[b_out->n]);
99 }
100 
101 inline double GetRectangleLowerLimit(unsigned int i,Trectangle *b)
102 {
103  assert(i<b->n);
104 
105  return(b->l[i]);
106 }
107 
108 inline double GetRectangleUpperLimit(unsigned int i,Trectangle *b)
109 {
110  assert(i<b->n);
111 
112  return(b->u[i]);
113 }
114 
115 inline void GetRectangleLimits(unsigned int i,double *l,double *u,Trectangle *b)
116 {
117  assert(i<b->n);
118 
119  *l=b->l[i];
120  *u=b->u[i];
121 }
122 
123 inline void SetRectangleLowerLimit(unsigned int i,double l,Trectangle *b)
124 {
125  assert(i<b->n);
126 
127  b->l[i]=l;
128 }
129 
130 inline void SetRectangleUpperLimit(unsigned int i,double u,Trectangle *b)
131 {
132  assert(i<b->n);
133 
134  b->u[i]=u;
135 }
136 
137 inline void SetRectangleLimits(unsigned int i,double l,double u,Trectangle *b)
138 {
139  assert(i<b->n);
140 
141  b->l[i]=l;
142  b->u[i]=u;
143 }
144 
146 {
147  unsigned int i;
148 
149  for(i=0;i<b->n;i++)
150  c[i]=b->l[i]+randomDouble()*(b->u[i]-b->l[i]);
151 }
152 
153 double SquaredDistanceToRectangleDimension(unsigned int dim,double p,unsigned int *tp,Trectangle *b)
154 {
155  double l,u,d,c,d1,d2,r;
156 
157  assert(dim<b->n);
158 
159  l=b->l[dim];
160  u=b->u[dim];
161  r=(u-l);
162  d=0.0;
163  if ((tp==NULL)||(tp[dim]==TOPOLOGY_R)||(r>M_2PI+ANGLE_ACCURACY))
164  {
165  /* topology real, or range larger than 2pi */
166  if (p<l)
167  d=l-p;
168  else
169  {
170  if (p>u)
171  d=p-u;
172  }
173  }
174  else
175  {
176  if (r<M_2PI-ANGLE_ACCURACY)
177  {
178  /* range < 2pi */
179  PI2PI(l);
180  PI2PI(u);
181  }
182  else
183  {
184  /* range == 2pi */
185  l=-M_PI;
186  u=+M_PI;
187  }
188 
189  c=p;
190  PI2PI(c);
191 
192  if (u<l)
193  {
194  /* The interval of interest is [-pi,u] U [l,pi] */
195  if ((u<c)&&(c<l))
196  {
197  d1=c-u;
198  d2=l-c;
199  d=(d1<d2?d1:d2);
200  }
201  }
202  else
203  {
204  /* The interval of interest is [l,u] */
205  if (c<l)
206  {
207  d1=l-c;
208  if (d1>M_PI) d1=M_2PI-d1;
209  d2=u-c;
210  if (d2>M_PI) d2=M_2PI-d2;
211  d=(d1<d2?d1:d2);
212  }
213  else
214  {
215  if (c>u)
216  {
217  d1=c-l;
218  if (d1>M_PI) d1=M_2PI-d1;
219  d2=c-u;
220  if (d2>M_PI) d2=M_2PI-d2;
221  d=(d1<d2?d1:d2);
222  }
223  }
224  }
225  }
226  return(d*d);
227 }
228 
229 
230 double SquaredDistanceToRectangle(double t2,double *p,unsigned int *tp,Trectangle *b)
231 {
232  unsigned int i;
233  double l,u,d,v,c,d1,d2,r;
234 
235  d=0.0;
236  if (tp==NULL)
237  {
238  /* topology real */
239  for(i=0;((i<b->n)&&(d<t2));i++)
240  {
241  l=b->l[i];
242  if (p[i]<l)
243  {
244  v=l-p[i];
245  d+=v*v;
246  }
247  else
248  {
249  u=b->u[i];
250  if (p[i]>u)
251  {
252  v=p[i]-u;
253  d+=v*v;
254  }
255  }
256  }
257  }
258  else
259  {
260  for(i=0;((i<b->n)&&(d<t2));i++)
261  {
262  l=b->l[i];
263  u=b->u[i];
264 
265  r=(u-l);
266  if ((tp[i]==TOPOLOGY_R)||(r>M_2PI+ANGLE_ACCURACY))
267  {
268  /* topology real, or range larger than 2pi */
269  if (p[i]<l)
270  {
271  v=l-p[i];
272  d+=v*v;
273  }
274  else
275  {
276  if (p[i]>u)
277  {
278  v=p[i]-u;
279  d+=v*v;
280  }
281  }
282  }
283  else
284  {
285  if (r<M_2PI-ANGLE_ACCURACY)
286  {
287  /* range < 2pi */
288  PI2PI(l);
289  PI2PI(u);
290  }
291  else
292  {
293  /* range == 2pi */
294  l=-M_PI;
295  u=+M_PI;
296  }
297 
298  c=p[i];
299  PI2PI(c);
300 
301  if (u<l)
302  {
303  /* The interval of interest is [-pi,u] U [l,pi] */
304  if ((u<c)&&(c<l))
305  {
306  d1=c-u;
307  d2=l-c;
308  v=(d1<d2?d1:d2);
309  d+=v*v;
310  }
311  }
312  else
313  {
314  /* The interval of interest is [l,u] */
315  if (c<l)
316  {
317  d1=l-c;
318  if (d1>M_PI) d1=M_2PI-d1;
319  d2=u-c;
320  if (d2>M_PI) d2=M_2PI-d2;
321  v=(d1<d2?d1:d2);
322  d+=v*v;
323  }
324  else
325  {
326  if (c>u)
327  {
328  d1=c-l;
329  if (d1>M_PI) d1=M_2PI-d1;
330  d2=c-u;
331  if (d2>M_PI) d2=M_2PI-d2;
332  v=(d1<d2?d1:d2);
333  d+=v*v;
334  }
335  }
336  }
337  }
338  }
339  }
340 
341  return(d);
342 }
343 
345 {
346  unsigned int i;
347  unsigned int i_max;
348  double s;
349  double s_max;
350 
351  i_max=0;
352  s_max=-1.0;
353  for(i=0;i<b->n;i++)
354  {
355  s=(b->u[i]-b->l[i]);
356  if (s>s_max)
357  {
358  s_max=s;
359  i_max=i;
360  }
361  }
362  return(i_max);
363 }
364 
365 void PrintRectangle(FILE *f,Trectangle *b)
366 {
367  unsigned int i;
368 
369  fprintf(f,"{ ");
370  for(i=0;i<b->n;i++)
371  fprintf(f,"[%f,%f] ",b->l[i],b->u[i]);
372  fprintf(f,"}");
373 }
374 
376 {
377  free(b->l);
378 }
double GetRectangleUpperLimit(unsigned int i, Trectangle *b)
Get the upper limit.
Definition: rectangle.c:108
void SetRectangleLowerLimit(unsigned int i, double l, Trectangle *b)
Set the lower limit.
Definition: rectangle.c:123
double SquaredDistanceToRectangle(double t2, double *p, unsigned int *tp, Trectangle *b)
Squared distance from a point to a rectangle.
Definition: rectangle.c:230
void ExpandRectangle(double *p, Trectangle *b)
Expands a rectangle so that it includes a given point.
Definition: rectangle.c:52
double * u
Definition: rectangle.h:29
#define NEWZ(_var, _n, _type)
Allocates memory space and initializes to zero.
Definition: definitions.h:98
double EnlargeRectangleWithLimits(double r, Trectangle *limits, Trectangle *bIn, Trectangle *bOut)
Enlarges a box remaining in a given limits.
Definition: rectangle.c:68
unsigned int GetRectangleDim(Trectangle *b)
Returns the dimension of the rectangle.
Definition: rectangle.c:47
void GetRectangleLimits(unsigned int i, double *l, double *u, Trectangle *b)
Gets the limits of the rectangle along a given dimension.
Definition: rectangle.c:115
double randomDouble()
Returns a random double in the [0,1] interval.
Definition: random.c:33
void SetRectangleUpperLimit(unsigned int i, double u, Trectangle *b)
Set the upper limit.
Definition: rectangle.c:130
void PrintRectangle(FILE *f, Trectangle *b)
Prints a rectangle.
Definition: rectangle.c:365
unsigned int GetRectangleSplitDim(Trectangle *b)
Computes the rectangle dimension for which it is better to split the rectangle.
Definition: rectangle.c:344
Definition of the Trectangle type and the associated functions.
#define PI2PI(a)
Forces an angle go be in [-pi,pi].
Definition: definitions.h:75
#define TOPOLOGY_R
One of the possible topologies.
Definition: definitions.h:180
#define NEW(_var, _n, _type)
Allocates memory space.
Definition: definitions.h:87
Definition of constants and macros used in several parts of the library.
void CopyRectangle(Trectangle *b_out, Trectangle *b_in)
Rectangle copy operator.
Definition: rectangle.c:91
#define M_2PI
2*Pi.
Definition: definitions.h:32
A rectangle.
Definition: rectangle.h:26
void DeleteRectangle(Trectangle *b)
Destructor.
Definition: rectangle.c:375
void SetRectangleLimits(unsigned int i, double l, double u, Trectangle *b)
Changes a rectangle along a given dimension.
Definition: rectangle.c:137
double SquaredDistanceToRectangleDimension(unsigned int dim, double p, unsigned int *tp, Trectangle *b)
Squared distance from a value to a given rectangle dimension.
Definition: rectangle.c:153
double * l
Definition: rectangle.h:28
void RandomPointInRectangle(double *c, Trectangle *b)
Returns the a random point along the selected dimensions.
Definition: rectangle.c:145
void InitRectangleFromPoint(unsigned int dim, double *p, Trectangle *b)
Initializes a rectangle from a point.
Definition: rectangle.c:35
Definition of basic randomization functions.
#define M_PI
Pi.
Definition: definitions.h:24
void InitRectangle(unsigned int dim, double *l, double *u, Trectangle *b)
Initializes a rectangle.
Definition: rectangle.c:20
unsigned int n
Definition: rectangle.h:27
double GetRectangleLowerLimit(unsigned int i, Trectangle *b)
Get the lower limit.
Definition: rectangle.c:101
#define ANGLE_ACCURACY
Accuracy used to compare angles.
Definition: definitions.h:44