From 0f05ee423d0a60f9f558f86f2404226c4bada49d Mon Sep 17 00:00:00 2001 From: cignoni Date: Wed, 4 Nov 2015 23:49:35 +0000 Subject: [PATCH] Added Fibonacci sampling, renamed to more meaningful names the sampling algs --- vcg/math/gen_normal.h | 110 ++++++++++++++++++++++++++++++++---------- 1 file changed, 84 insertions(+), 26 deletions(-) diff --git a/vcg/math/gen_normal.h b/vcg/math/gen_normal.h index 757d47a6..6e94bcb2 100644 --- a/vcg/math/gen_normal.h +++ b/vcg/math/gen_normal.h @@ -55,6 +55,33 @@ static void Random(int vn, std::vector > &NN) } } } + + +static Point3x FibonacciPt(int i, int n) +{ + const ScalarType Phi = ScalarType(sqrt(5)*0.5 + 0.5); + const ScalarType phi = 2.0*M_PI* (i/Phi - floor(i/Phi)); + ScalarType cosTheta = 1.0 - (2*i + 1.0)/ScalarType(n); + float sinTheta = 1 - cosTheta*cosTheta; + sinTheta = sqrt(std::min(ScalarType(1),std::max(ScalarType(0),sinTheta))); + return Point3x( + cos(phi)*sinTheta, + sin(phi)*sinTheta, + cosTheta); +} + +// Implementation of the Spherical Fibonacci Point Sets +// according to the description of +// Spherical Fibonacci Mapping +// Benjamin Keinert, Matthias Innmann, Michael Sanger, Marc Stamminger +// TOG 2015 +static void Fibonacci(int n, std::vector &NN) +{ + NN.resize(n); + for(int i=0;i > &NN, ScalarType AngleRad, Point3x dir=Point3x(0,1,0)) { std::vector > NNT; @@ -66,14 +93,14 @@ static void UniformCone(int vn, std::vector > &NN, ScalarTyp ScalarType Ratio = CapArea / (4.0*M_PI ); printf("----------AngleRad %f Angledeg %f ratio %f vn %i vn2 %i \n",AngleRad,math::ToDeg(AngleRad),Ratio,vn,int(vn/Ratio)); - Uniform(vn/Ratio,NNT); + Fibonacci(vn/Ratio,NNT); printf("asked %i got %i (expecting %i instead of %i)\n", int(vn/Ratio), NNT.size(), int(NNT.size()*Ratio), vn); typename std::vector >::iterator vi; - ScalarType DotProd = cos(AngleRad); + ScalarType cosAngle = cos(AngleRad); for(vi=NNT.begin();vi!=NNT.end();++vi) { - if(dir.dot(*vi) >= DotProd) NN.push_back(*vi); + if(dir.dot(*vi) >= cosAngle) NN.push_back(*vi); } } @@ -90,7 +117,7 @@ static void UniformCone(int vn, std::vector > &NN, ScalarTyp // 2+ 2N*Sum(i=1 to N-1) sin(pi i/N). // The closed form of this summation // 2.0 - ( (2.0*N * sin (M_PI/N))/(cos(M_PI/N) - 1.0)); -static void Regular(int vn, std::vector > &NN) +static void DiscoBall(int vn, std::vector > &NN) { // Guess the right N ScalarType N=0; @@ -98,11 +125,9 @@ static void Regular(int vn, std::vector > &NN) for(N=1;N %f",N,expectedPoints); if(expectedPoints >= vn) break; } - ScalarType VerticalAngle = M_PI / N; NN.push_back(Point3(0,0,1.0)); for (int i =1; i > &NN) NN.push_back(Point3(0,0,-1.0)); } -static void Uniform(int vn, std::vector > &NN) +static void RecursiveOctahedron(int vn, std::vector > &NN) { OctaLevel pp; @@ -136,7 +161,7 @@ static void Uniform(int vn, std::vector > &NN) pp.v.resize(newsize); NN=pp.v; - Perturb(NN); + //Perturb(NN); } static void Perturb(std::vector > &NN) @@ -187,46 +212,79 @@ class OctaLevel std::vector v; int level; int sz; + int sz2; Point3x &Val(int i, int j) { - assert(i>=0 && i=0 && j=-sz2 && i<=sz2); + assert(j>=-sz2 && j<=sz2); + return v[i+sz2 +(j+sz2)*sz]; + } +/* + * Only the first quadrant is generated and replicated onto the other ones. + * + * o lev == 1 + * | \ sz2 = 2^lev = 2 + * o - o sz = 5 (eg. all the points lie in a 5x5 squre) + * | \ | \ + * o - o - o + * + * | + * V + * + * o + * | \ lev == 1 + * o - o sz2 = 4 + * | \ | \ sz = 9 (eg. all the points lie in a 9x9 squre) + * o - o - o + * | \ | \ | \ + * o - o - o - o + * | \ | \ | \ | \ + * o - o - o - o - o + * + * + */ void Init(int lev) { - sz=pow(2.0f,lev+1)+1; - v.resize(sz*sz); + sz2=pow(2.0f,lev); + sz=sz2*2+1; + v.resize(sz*sz,Point3x(0,0,0)); if(lev==0) { - Val(0,0)=Point3x( 0, 0,-1); Val(0,1)=Point3x( 0, 1, 0); Val(0,2)=Point3x( 0, 0,-1); - - Val(1,0)=Point3x(-1, 0, 0); Val(1,1)=Point3x( 0, 0, 1); Val(1,2)=Point3x( 1, 0, 0); - - Val(2,0)=Point3x( 0, 0,-1); Val(2,1)=Point3x( 0,-1, 0); Val(2,2)=Point3x( 0, 0,-1); + Val( 0,0)=Point3x( 0, 0, 1); + Val( 1,0)=Point3x( 1, 0, 0); + Val( 0,1)=Point3x( 0, 1, 0); } else { OctaLevel tmp; tmp.Init(lev-1); int i,j; - for(i=0;i >::iterator vi; + + typename std::vector >::iterator vi; for(vi=v.begin(); vi!=v.end();++vi) (*vi).Normalize(); - } } };