replace rand() with MarsenneTwister generator
This commit is contained in:
parent
51e1718626
commit
3586a13438
|
@ -89,25 +89,43 @@ class SurfaceSampling
|
||||||
typedef typename MetroMesh::FaceContainer FaceContainer;
|
typedef typename MetroMesh::FaceContainer FaceContainer;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
static math::SubtractiveRingRNG &SamplingRandomGenerator()
|
static math::MarsenneTwisterRNG &SamplingRandomGenerator()
|
||||||
{
|
{
|
||||||
static math::SubtractiveRingRNG rnd;
|
static math::MarsenneTwisterRNG rnd;
|
||||||
return rnd;
|
return rnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned int RandomInt(unsigned int i) { return SamplingRandomGenerator().generate(i); }
|
// Returns an integer random number in the [0,i-1] interval using the improve Marsenne-Twister method.
|
||||||
|
static unsigned int RandomInt(unsigned int i)
|
||||||
|
{
|
||||||
|
return (SamplingRandomGenerator().generate(0) % i);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns a random number in the [0,1) real interval using the improved Marsenne-Twister method.
|
||||||
|
static double RandomDouble01()
|
||||||
|
{
|
||||||
|
return SamplingRandomGenerator().generate01();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns a random number in the [0,1] real interval using the improved Marsenne-Twister.
|
||||||
|
static double RandomDouble01closed()
|
||||||
|
{
|
||||||
|
return SamplingRandomGenerator().generate01closed();
|
||||||
|
}
|
||||||
|
|
||||||
static void AllVertex(MetroMesh & m, VertexSampler &ps)
|
static void AllVertex(MetroMesh & m, VertexSampler &ps)
|
||||||
{
|
{
|
||||||
VertexIterator vi;
|
VertexIterator vi;
|
||||||
for(vi=m.vert.begin();vi!=m.vert.end();++vi)
|
for(vi=m.vert.begin();vi!=m.vert.end();++vi)
|
||||||
|
{
|
||||||
if(!(*vi).IsD())
|
if(!(*vi).IsD())
|
||||||
{
|
{
|
||||||
ps.AddVert(*vi);
|
ps.AddVert(*vi);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sample the vertices in a weighted way. Each vertex has a probabiltiy of being chosen
|
/// Sample the vertices in a weighted way. Each vertex has a probability of being chosen
|
||||||
/// that is proportional to its quality.
|
/// that is proportional to its quality.
|
||||||
/// It assumes that you are asking a number of vertices smaller than nv;
|
/// It assumes that you are asking a number of vertices smaller than nv;
|
||||||
/// Algorithm:
|
/// Algorithm:
|
||||||
|
@ -278,14 +296,14 @@ static void AllEdge(MetroMesh & m, VertexSampler &ps)
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Generate the baricentric coords of a random point over a single face, with a uniform distribution over the triangle.
|
// Generate the barycentric coords of a random point over a single face,
|
||||||
// It uses the parallelgoram folding trick.
|
// with a uniform distribution over the triangle.
|
||||||
|
// It uses the parallelogram folding trick.
|
||||||
static CoordType RandomBaricentric()
|
static CoordType RandomBaricentric()
|
||||||
{
|
{
|
||||||
CoordType interp;
|
CoordType interp;
|
||||||
interp[1] = (double)rand() / (double)RAND_MAX;
|
interp[1] = RandomDouble01();
|
||||||
interp[2] = (double)rand() / (double)RAND_MAX;
|
interp[2] = RandomDouble01();
|
||||||
if(interp[1] + interp[2] > 1.0)
|
if(interp[1] + interp[2] > 1.0)
|
||||||
{
|
{
|
||||||
interp[1] = 1.0 - interp[1];
|
interp[1] = 1.0 - interp[1];
|
||||||
|
@ -326,7 +344,7 @@ static void Montecarlo(MetroMesh & m, VertexSampler &ps,int sampleNum)
|
||||||
FaceIterator fi;
|
FaceIterator fi;
|
||||||
int i=0;
|
int i=0;
|
||||||
intervals[i]=std::make_pair(0,FacePointer(0));
|
intervals[i]=std::make_pair(0,FacePointer(0));
|
||||||
// First loop: build a sequence of consective segments proportional to the triangle areas.
|
// First loop: build a sequence of consecutive segments proportional to the triangle areas.
|
||||||
for(fi=m.face.begin(); fi != m.face.end(); fi++)
|
for(fi=m.face.begin(); fi != m.face.end(); fi++)
|
||||||
if(!(*fi).IsD())
|
if(!(*fi).IsD())
|
||||||
{
|
{
|
||||||
|
@ -336,7 +354,7 @@ static void Montecarlo(MetroMesh & m, VertexSampler &ps,int sampleNum)
|
||||||
ScalarType meshArea = intervals.back().first;
|
ScalarType meshArea = intervals.back().first;
|
||||||
for(i=0;i<sampleNum;++i)
|
for(i=0;i<sampleNum;++i)
|
||||||
{
|
{
|
||||||
ScalarType val = meshArea * (double)rand() / (double)RAND_MAX;
|
ScalarType val = meshArea * RandomDouble01();
|
||||||
// lower_bound returns the furthermost iterator i in [first, last) such that, for every iterator j in [first, i), *j < value.
|
// lower_bound returns the furthermost iterator i in [first, last) such that, for every iterator j in [first, i), *j < value.
|
||||||
// E.g. An iterator pointing to the first element "not less than" val, or end() if every element is less than val.
|
// E.g. An iterator pointing to the first element "not less than" val, or end() if every element is less than val.
|
||||||
typename std::vector<IntervalType>::iterator it = lower_bound(intervals.begin(),intervals.end(),std::make_pair(val,FacePointer(0)) );
|
typename std::vector<IntervalType>::iterator it = lower_bound(intervals.begin(),intervals.end(),std::make_pair(val,FacePointer(0)) );
|
||||||
|
|
Loading…
Reference in New Issue