From 90bb95a9712a95dd9a0d669688fea02a6a06b909 Mon Sep 17 00:00:00 2001 From: cignoni Date: Mon, 24 Jun 2013 08:34:53 +0000 Subject: [PATCH] Refactorized to a uniform naming and parameters the various templated functions for generating random points GenerateBarycentricUniform GeneratePointInBox3Uniform GeneratePointOnUnitSphereUniform GeneratePointInUnitBallUniform --- vcg/math/random_generator.h | 52 ++++++++++++++++++++++++++++++++----- 1 file changed, 46 insertions(+), 6 deletions(-) diff --git a/vcg/math/random_generator.h b/vcg/math/random_generator.h index f7955de3..442cdd38 100644 --- a/vcg/math/random_generator.h +++ b/vcg/math/random_generator.h @@ -62,20 +62,42 @@ public: /// Generates a random number in the (0,1) real interval. virtual double generate01open()=0; - virtual double generateRange(double minV, double maxV) { return minV+(maxV-minV)*generate01(); } + virtual double generateRange(double minV, double maxV) { return minV+(maxV-minV)*generate01(); } }; +/// \brief Generate the barycentric coords of a random point over a single face, +/// with a uniform distribution over the triangle. +/// It uses the parallelogram folding trick. template -void GeneratePointInBox3Uniform(GeneratorType &rnd, const Box3 &bb, Point3 &p) +vcg::Point3 GenerateBarycentricUniform(GeneratorType &rnd) { - p = Point3( - (ScalarType) rnd.generateRange(double(bb.min[0]),double(bb.max[0])), + vcg::Point3 interp; + interp[1] = rnd.generate01(); + interp[2] = rnd.generate01(); + if(interp[1] + interp[2] > 1.0) + { + interp[1] = 1.0 - interp[1]; + interp[2] = 1.0 - interp[2]; + } + + assert(interp[1] + interp[2] <= 1.0); + interp[0]=1.0-(interp[1] + interp[2]); + return interp; +} + +/// \brief Generate a random point insidie a box with uniform distribution +template +vcg::Point3 GeneratePointInBox3Uniform(GeneratorType &rnd, const Box3 &bb) +{ + return Point3( + (ScalarType) rnd.generateRange(double(bb.min[0]),double(bb.max[0])), (ScalarType) rnd.generateRange(double(bb.min[1]),double(bb.max[1])), (ScalarType) rnd.generateRange(double(bb.min[2]),double(bb.max[2])) ); } -/* + +/** \brief Generate a point over the surface of a unit sphere with uniform distribution * This is the algorithm proposed by George Marsaglia [1] * to generate a point over a unit sphere * Independently generate V1 and V2, taken from a uniform distribution on (-1,1) such that @@ -87,8 +109,9 @@ void GeneratePointInBox3Uniform(GeneratorType &rnd, const Box3 &bb, * Marsaglia, G. "Choosing a Point from the Surface of a Sphere." Ann. Math. Stat. 43, 645-646, 1972. */ template -void GeneratePointOnUnitSphereUniform(GeneratorType &rnd, vcg::Point3 &p) +vcg::Point3 GeneratePointOnUnitSphereUniform(GeneratorType &rnd) { + vcg::Point3 p; double x,y,s; do { @@ -99,8 +122,25 @@ void GeneratePointOnUnitSphereUniform(GeneratorType &rnd, vcg::Point3 +vcg::Point3 GeneratePointInUnitBallUniform(GeneratorType &rnd) +{ + vcg::Point3 p; + while(1) + { + p.Import(Point3d(0.5-rnd.generate01(),0.5-rnd.generate01(),0.5-rnd.generate01())); + if(SquaredNorm(p)<=0.25){ + p*=2; + return p; + } + } +} + + /** * Uniform RNG derived from a STL extension of sgi. *