IMP  2.1.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 /** See BoundingBoxD
36  See VectorD
37  */
38 template <int D>
41 }
42 
43 //! Generate a random vector on a box with uniform density
44 /** See BoundingBoxD
45  See VectorD
46  */
47 template <int D>
49  return internal::RandomVectorOnBB<D>::get(bb);
50 }
51 
52 //! Generate a random vector in a sphere with uniform density
53 /** See VectorD
54  See SphereD
55  */
56 template <int D>
59  double norm;
60  VectorD<D> ret;
61  double r2 = get_squared(s.get_radius());
62  // \todo This algorithm could be more efficient.
63  do {
64  ret = get_random_vector_in(bb);
65  norm = (s.get_center() - ret).get_squared_magnitude();
66  } while (norm > r2);
67  return ret;
68 }
69 
70 /** Generates a random vector in a circle
71  with uniform density with respect to the area of the circle
72 
73  @param s a 2D sphere (circle)
74 
75  See VectorD
76  See SphereD
77 */
78 IMPALGEBRAEXPORT VectorD<2> get_random_vector_in(const SphereD<2> &s);
79 
80 //! Generate a random vector in a cylinder with uniform density
81 /** See VectorD
82  See Cylinder3D
83  */
84 IMPALGEBRAEXPORT Vector3D get_random_vector_in(const Cylinder3D &c);
85 
86 //! Generate a random vector on a sphere with uniform density
87 /** See VectorD
88  See SphereD
89  */
90 template <int D>
93 }
94 
95 //! Generate a set of vectors which covers a sphere uniformly
96 /** The function is currently pretty slow, especially in non-optimized
97  builds. Complain if this bugs you. We might be able to do better,
98  at least in 3D.
99 
100  Creates at least the requested number of points.
101  \cgalpredicate
102 
103  See VectorD
104  See SphereD
105  */
106 template <int D>
108  unsigned int n) {
109  return internal::uniform_cover_sphere(n, s.get_center(), s.get_radius(),
110  true);
111 }
112 
113 //! Generate a set of 3d points that uniformly cover a cylinder
114 /** See VectorD
115  See Cylinder3D
116 */
117 IMPALGEBRAEXPORT Vector3Ds
118  get_uniform_surface_cover(const Cylinder3D &cyl, int number_of_points);
119 
120 //! Generate a set of 3D points that uniformly cover a hemisphere
121 /** The points all lie on the upper hemisphere, eg, all their
122  z coordinates are greater than those of the center of the sphere.
123  */
124 template <int D>
126  const SphereD<D> &s, unsigned int n) {
127  return internal::uniform_cover_sphere(n, s.get_center(), s.get_radius(),
128  false);
129 }
130 
131 //! Generate a grid of 3d points on a cylinder surface
132 /** See Vector3D
133  See Cylinder3D
134 */
135 IMPALGEBRAEXPORT Vector3Ds
136  get_grid_surface_cover(const Cylinder3D &cyl, int number_of_cycles,
137  int number_of_points_on_cycle);
138 
139 //! Generate a set of 3d points that uniformly cover a patch of a sphere
140 /**
141  \note the implementation can be improved
142  See SpherePatch3D
143  See VectorD
144  */
145 IMPALGEBRAEXPORT Vector3Ds
146  get_uniform_surface_cover(const SpherePatch3D &sph,
147  unsigned int number_of_points);
148 
149 /** See VectorD
150  See Cone3D
151 */
152 IMPALGEBRAEXPORT Vector3Ds
153  get_uniform_surface_cover(const Cone3D &cone,
154  unsigned int number_of_points);
155 
156 /** Cover the interior of the bounding box by equal sized
157  parallelograms of approximately full-width s, returning the
158  list of centers of the cubes.
159  */
160 template <int D>
162  const BoundingBoxD<D> &bb, double s) {
163  const unsigned int dim = bb.get_dimension();
164  Ints ns(dim);
165  algebra::VectorD<D> start(bb.get_corner(0));
166  algebra::VectorD<D> spacing(bb.get_corner(0));
167  for (unsigned int i = 0; i < dim; ++i) {
168  double w = bb.get_corner(1)[i] - bb.get_corner(0)[i];
169  if (w < s) {
170  start[i] = bb.get_corner(0)[i] + w * .5;
171  spacing[i] = 1;
172  ns[i] = 1;
173  } else {
174  ns[i] = static_cast<int>(std::floor(w / s));
175  spacing[i] = w / ns[i];
176  start[i] = bb.get_corner(0)[i] + spacing[i] * .5;
177  }
178  }
179  Ints cur(D, 0);
181  do {
182  ret.push_back(start + get_elementwise_product(cur, spacing));
183  unsigned int i;
184  for (i = 0; i < dim; ++i) {
185  ++cur[i];
186  if (cur[i] == ns[i]) {
187  cur[i] = 0;
188  } else {
189  break;
190  }
191  }
192  if (i == dim) break;
193  } while (true);
194  return ret;
195 }
196 
197 //! Generate a random chain with no collisions
198 /** This function generates a random chain, starting at (0,0,0)
199  with n particles each with radius r. Consecutive particles are
200  approximately distance 2r apart and no pair of particles is closer
201  than 2r.
202 
203  If an obstacles parameter is provided then chain spheres also don't
204  intersect the obstacle spheres.
205 
206  \note The current implementation is not very clever and can be made
207  more clever if needed.
208  */
209 IMPALGEBRAEXPORT Vector3Ds
210  get_random_chain(unsigned int n, double r,
211  const Vector3D &start = Vector3D(0, 0, 0),
212  const Sphere3Ds &obstacles = Sphere3Ds());
213 
214 /** @} */
215 
216 IMPALGEBRA_END_NAMESPACE
217 
218 #endif /* IMPALGEBRA_VECTOR_GENERATORS_H */
IMP::base::Vector< Sphere3D > Sphere3Ds
Definition: SphereD.h:89
base::Vector< VectorD< D > > get_uniform_upper_hemisphere_cover(const SphereD< D > &s, unsigned int n)
Generate a set of 3D points that uniformly cover a hemisphere.
VectorD< D > get_random_vector_on(const BoundingBoxD< D > &bb)
Generate a random vector on a box with uniform density.
Simple 3D sphere patch class.
VectorD< D > get_elementwise_product(const algebra::VectorD< D > &a, const algebra::VectorD< D > &b)
Definition: VectorD.h:622
const VectorD< D > & get_corner(unsigned int i) const
For 0 return lower corner and 1 upper corner.
Definition: BoundingBoxD.h:123
base::Vector< VectorD< D > > get_uniform_surface_cover(const SphereD< D > &s, unsigned int n)
Generate a set of vectors which covers a sphere uniformly.
stores a cylinder
Vector3Ds get_random_chain(unsigned int n, double r, const Vector3D &start=Vector3D(0, 0, 0), const Sphere3Ds &obstacles=Sphere3Ds())
Generate a random chain with no collisions.
base::Vector< VectorD< 3 > > Vector3Ds
Definition: VectorD.h:589
Functions to deal with very common math operations.
A Cartesian vector in D-dimensions.
Definition: VectorD.h:48
A bounding box in D dimensions.
VectorD< D > get_random_vector_in(const BoundingBoxD< D > &bb)
Generate a random vector in a box with uniform density.
Simple D vector class.
An axis-aligned bounding box.
Definition: BoundingBoxD.h:26
base::Vector< VectorD< D > > get_grid_interior_cover_by_spacing(const BoundingBoxD< D > &bb, double s)
stores a cone
VectorD< 3 > Vector3D
Definition: VectorD.h:587
Simple 3D sphere class.
Vector3Ds get_grid_surface_cover(const Cylinder3D &cyl, int number_of_cycles, int number_of_points_on_cycle)
Generate a grid of 3d points on a cylinder surface.
BoundingBoxD< D > get_bounding_box(const BoundingBoxD< D > &g)
Definition: BoundingBoxD.h:160