Vertices<CoordType> SpatialModelMaximalRepulsion3D<CoordType>::drawSample(const int numPoints)
{
  ENTER("Vertices<CoordType> SpatialModelMaximalRepulsion3D<CoordType>::drawSample(const int)");

  const int outerSteps = getNumMonteCarloCycles();
  const int innerSteps = numPoints;
  const CoordType beta = computeBeta();
  const CoordType maxRadius = this->getTriMesh().equivalentRadius() / 50.0;
  Vertices<CoordType> vertices = SpatialModelHardcoreDistance3D<CoordType>::drawSample( numPoints );
  RandomGenerator& randomGenerator = this->getRandomGenerator();
  CoordType currentEnergy, newEnergy, deltaEnergy;
  Vector<CoordType> vertex;
  bool acceptTransition;
  int i, j, v;

  ConvergenceTest<CoordType> convergenceTest;  
  CoordType sumEnergy;
  bool converged = false;
  _energyProfile.setZeros( outerSteps );
  convergenceTest.setData( _energyProfile );
  convergenceTest.setRange( 100 );

  for (i = 0; !converged && i < outerSteps; ++i)
  {
#if 0
    if ( (i%20)==0 )
    {
      string filename = "max-repulsion-vertices-" + StringTools::toString(i,4,'0') + ".vx";
      vertices.save( filename, true );
    }
#endif
    for (j = 0, sumEnergy = 0.0; j < innerSteps; ++j)
    {
      v = randomGenerator.uniformL( numPoints );
      vertex = vertices[v];
      if ( j == 0 ) currentEnergy = energy( vertices );
      moveVertex( vertices, v, maxRadius );
      newEnergy = energy( vertices );
      deltaEnergy = newEnergy - currentEnergy;
      acceptTransition = deltaEnergy <= .0 || randomGenerator.uniformLF() < exp( -beta*deltaEnergy );

      if ( acceptTransition )
        currentEnergy = newEnergy;
      else vertices[v] = vertex;
      sumEnergy += currentEnergy;
    }

    _energyProfile[i] = sumEnergy / innerSteps;
    converged = convergenceTest.isPositive( i );
  }

  if ( !converged )
  {
    Exception exception;
    exception.setWhere( "Vertices<CoordType> SpatialModelMaximalRepulsion3D<CoordType>::drawSample(const int)" );
    exception.setWhat( "Convergence not reached after " + StringTools::toString(outerSteps) + " iterations" );
    throw exception;
  }

  LEAVE();

  return vertices;
}