IMP  2.0.0
The Integrative Modeling Platform
vector_generators.h
Go to the documentation of this file.
1 /**
2  * \file IMP/algebra/vector_generators.h
3  * \brief Functions to generate vectors.
4  *
5  * Copyright 2007-2013 IMP Inventors. All rights reserved.
6  *
7  */
8 
9 #ifndef IMPALGEBRA_VECTOR_GENERATORS_H
10 #define IMPALGEBRA_VECTOR_GENERATORS_H
11 
12 #include "VectorD.h"
13 #include "Cylinder3D.h"
14 #include "Cone3D.h"
15 #include "Sphere3D.h"
16 #include "SpherePatch3D.h"
17 #include "BoundingBoxD.h"
18 #include "utility.h"
19 #include "internal/grid_range_d.h"
20 #include "internal/internal_vector_generators.h"
21 
22 IMPALGEBRA_BEGIN_NAMESPACE
23 
24 /** @name Vector Generators
25 
26  These functions generate vector objects. Some
27  of the methods, those with random in their name, generate
28  a single vector chosen uniformly from the specified domain.
29  Others, the cover methods, generate a set of points distributed
30  (somewhat) evenly over the domain.
31  @{
32  */
33 
34 //! Generate a random vector in a box with uniform density
35 /** \relatesalso BoundingBoxD
36  \relatesalso VectorD
37  */
38 template <int D>
39 inline VectorD<D>
42 }
43 
44 //! Generate a random vector on a box with uniform density
45 /** \relatesalso BoundingBoxD
46  \relatesalso VectorD
47  */
48 template <int D>
49 inline VectorD<D>
51  return internal::RandomVectorOnBB<D>::get(bb);
52 }
53 
54 
55 //! Generate a random vector in a sphere with uniform density
56 /** \relatesalso VectorD
57  \relatesalso SphereD
58  */
59 template <int D>
60 inline VectorD<D>
63  double norm;
64  VectorD<D> ret;
65  double r2= get_squared(s.get_radius());
66  // \todo This algorithm could be more efficient.
67  do {
68  ret=get_random_vector_in(bb);
69  norm= (s.get_center()- ret).get_squared_magnitude();
70  } while (norm > r2);
71  return ret;
72 }
73 
74 /** Generates a random vector in a circle
75  with uniform density with respect to the area of the circle
76 
77  @param s a 2D sphere (circle)
78 
79  \relatesalso VectorD
80  \relatesalso SphereD
81 */
82 IMPALGEBRAEXPORT
83 VectorD<2>
84 get_random_vector_in(const SphereD<2> &s);
85 
86 
87 //! Generate a random vector in a cylinder with uniform density
88 /** \relatesalso VectorD
89  \relatesalso Cylinder3D
90  */
91 IMPALGEBRAEXPORT
93 get_random_vector_in(const Cylinder3D &c);
94 
95 
96 //! Generate a random vector on a sphere with uniform density
97 /** \relatesalso VectorD
98  \relatesalso SphereD
99  */
100 template <int D>
101 inline VectorD<D>
104 }
105 
106 
107 //! Generate a set of vectors which covers a sphere uniformly
108 /** The function is currently pretty slow, especially in non-optimized
109  builds. Complain if this bugs you. We might be able to do better,
110  at least in 3D.
111 
112  Creates at least the requested number of points.
113  \cgalpredicate
114 
115  \relatesalso VectorD
116  \relatesalso SphereD
117  */
118 template <int D>
120 get_uniform_surface_cover(const SphereD<D> &s, unsigned int n) {
121  return internal::uniform_cover_sphere(n, s.get_center(),
122  s.get_radius(), true);
123 }
124 
125 
126 //! Generate a set of 3d points that uniformly cover a cylinder
127 /** \relatesalso VectorD
128  \relatesalso Cylinder3D
129 */
130 IMPALGEBRAEXPORT Vector3Ds
131 get_uniform_surface_cover(const Cylinder3D &cyl,
132  int number_of_points);
133 
134 //! Generate a set of 3D points that uniformly cover a hemisphere
135 /** The points all lie on the upper hemisphere, eg, all their
136  z coordinates are greater than those of the center of the sphere.
137  */
138 template <int D>
141  return internal::uniform_cover_sphere(n, s.get_center(),
142  s.get_radius(), false);
143 }
144 
145 //! Generate a grid of 3d points on a cylinder surface
146 /** \relatesalso Vector3D
147  \relatesalso Cylinder3D
148 */
149 IMPALGEBRAEXPORT Vector3Ds
150 get_grid_surface_cover(const Cylinder3D &cyl,
151  int number_of_cycles,
152  int number_of_points_on_cycle);
153 
154 
155 
156 //! Generate a set of 3d points that uniformly cover a patch of a sphere
157 /**
158  \note the implementation can be improved
159  \relatesalso SpherePatch3D
160  \relatesalso VectorD
161  */
162 IMPALGEBRAEXPORT Vector3Ds
163 get_uniform_surface_cover(const SpherePatch3D &sph,
164  unsigned int number_of_points);
165 
166 /** \relatesalso VectorD
167  \relatesalso Cone3D
168 */
169 IMPALGEBRAEXPORT Vector3Ds
170 get_uniform_surface_cover(const Cone3D &cone,
171  unsigned int number_of_points);
172 
173 /** Cover the interior of the bounding box by equal sized
174  parallelograms of approximately full-width s, returning the
175  list of centers of the cubes.
176  */
177 template <int D>
180  const unsigned int dim= bb.get_dimension();
181  Ints ns(dim);
182  algebra::VectorD<D> start(bb.get_corner(0));
183  algebra::VectorD<D> spacing(bb.get_corner(0));
184  for (unsigned int i=0; i< dim; ++i) {
185  double w= bb.get_corner(1)[i]- bb.get_corner(0)[i];
186  if (w < s) {
187  start[i]= bb.get_corner(0)[i]+w*.5;
188  spacing[i]=1;
189  ns[i]=1;
190  } else {
191  ns[i]= static_cast<int>(std::floor(w/s));
192  spacing[i]= w/ns[i];
193  start[i]=bb.get_corner(0)[i]+spacing[i]*.5;
194  }
195  }
196  Ints cur(D,0);
198  do {
199  ret.push_back(start+get_elementwise_product(cur, spacing));
200  unsigned int i;
201  for (i=0; i< dim; ++i) {
202  ++cur[i];
203  if (cur[i]==ns[i]) {
204  cur[i]=0;
205  } else {
206  break;
207  }
208  }
209  if (i==dim) break;
210  } while(true);
211  return ret;
212 }
213 
214 
215 //! Generate a random chain with no collisions
216 /** This function generates a random chain, starting at (0,0,0)
217  with n particles each with radius r. Consecutive particles are
218  approximately distance 2r apart and no pair of particles is closer
219  than 2r.
220 
221  If an obstacles parameter is provided then chain spheres also don't
222  intersect the obstacle spheres.
223 
224  \note The current implementation is not very clever and can be made
225  more clever if needed.
226  */
227 IMPALGEBRAEXPORT Vector3Ds
228 get_random_chain(unsigned int n, double r,
229  const Vector3D &start
230  = Vector3D(0,0,0),
231  const Sphere3Ds &obstacles
232  =Sphere3Ds());
233 
234 /** @} */
235 
236 IMPALGEBRA_END_NAMESPACE
237 
238 #endif /* IMPALGEBRA_VECTOR_GENERATORS_H */